Python:如何循环遍历连续的字符?

15
在 Python 中(特别是 Python 3.0 但我认为不重要),如何轻松地编写一个循环来访问一系列具有连续字符编码的字符?我想做类似于这个伪代码的操作:
for Ch from 'a' to 'z' inclusive: #
    f(Ch)

例如:如何使用“Pythonic”的方式改写以下代码?

def Pangram(Str):
    ''' Returns True if Str contains the whole alphabet, else False '''
    for Ch from 'a' to 'z' inclusive: #
        M[Ch] = False
    for J in range(len(Str)):
        Ch = lower(Str[J])
        if 'a' <= Ch <= 'z':
            M[Ch] = True
    return reduce(and, M['a'] to M['z'] inclusive) #

这些带#标记的行是伪代码。当然,reduce()是真正的Python语言!

尊敬的巫师们(特别是年迈、留着灰色胡须的巫师们),也许你们能看出我的最喜欢的编程语言曾经是Pascal。

6个回答

44

在字符串模块中有一个称为ascii_lowercase的常量,可以尝试使用它:

>>> from string import ascii_lowercase

然后您可以迭代该字符串中的字符。

>>> for i in ascii_lowercase :
...     f(i)

对于你的字母表问题,有一种非常简单的方法可以确定一个字符串是否包含了字母表中的所有字母。与之前一样,使用ascii_lowercase:

>>> def pangram(str) :
...     return set(ascii_lowercase).issubset(set(str))

如果我也能成为一个巫师,我就会留着胡须生活 :) - sykora
你也可以使用 <= 来检查集合是否为子集:set(ascii_lowercase) <= set(str) - Moshe

20

使用包含所需所有字符的常量进行迭代非常Pythonic。但是,如果您不想导入任何内容并且仅在Unicode中工作,请使用内置函数 ord() 和它的逆 chr()。

for code in range(ord('a'), ord('z') + 1):
     print chr(code)

还有一件事:如果你想要范围包括末尾值,使用如下代码:
for code in range(ord('a'), ord('z')+1): print unichr(code)
- Ryan Ginstrom
1
不建议禁止从标准库导入。 - user3850
正是我所需要的!其他解决方案无法处理在运行时确定的字母范围。 - Paul
1
这不包括 'z'。需要 ord('z') + 1 - stanleyli
已经修复了@stanleyli。谢谢。 - Bluu

6

你必须放弃Pascal式的编程思维,以全新的视角学习Python。

>>> ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
>>> def pangram( source ):
    return all(c in source for c in ascii_lowercase)

>>> pangram('hi mom')
False
>>> pangram(ascii_lowercase)
True

如果你只局限于Pascal提供的东西,那么你将错失Python提供的一切。

另外...尽量避免使用reduce。它经常会导致可怕的性能问题。


编辑。这里有另一种表述方式; 这个实现了集合交集。

>>> def pangram( source ):
>>>     notused= [ c for c in ascii_lowercase if c not in source ]
>>>     return len(notused) == 0

这个工具为您提供一条诊断信息,以确定候选句中缺失的字母。

抱歉,生成器表达式在2.4及以上版本中才有,而不是2.3。 - user3850
@hop:我不理解这个注释。代码更改看起来很好,但是注释不够清晰易懂。 - S.Lott
@s.lott:我在更改的注释中写道,GEs适用于2.3+。 - user3850
@hop:明白了——你移除了列表推导式,因为它不再需要。 - S.Lott

2
更抽象的回答可能是这样的:
>>> x="asdf"
>>> for i in range(len(x)):
...     print x[i]

1

Hacky

method_1 = [chr(x) for x in range(ord('a'), ord('z')+1)]
print(method_1)

Neat
# this is the recommended method generally 
from string import ascii_lowercase  
method_2 = [x for x in ascii_lowercase]
print(method_2)

0
我会编写一个类似于Python的range函数。
def alpha_range(*args):
  if len(args) == 1:
    start, end, step = ord('a'), ord(args[0]), 1
  elif len(args) == 2:
    start, end, step = ord(args[0]), ord(args[1]), 1
  else:
    start, end, step = ord(args[0]), ord(args[1]), args[2]
  return (chr(i) for i in xrange(start, end, step))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接