在python中的字符范围


78

有没有办法覆盖字符?这样的事情。

for c in xrange( 'a', 'z' ):
    print c

希望你们能帮上忙。


17
如果你只是想英文字母,还有import stringstring.ascii_lowercase
Thomas K

Answers:


101

这对于自定义生成器很有用:

Python 2:

def char_range(c1, c2):
    """Generates the characters from `c1` to `c2`, inclusive."""
    for c in xrange(ord(c1), ord(c2)+1):
        yield chr(c)

然后:

for c in char_range('a', 'z'):
    print c

Python 3:

def char_range(c1, c2):
    """Generates the characters from `c1` to `c2`, inclusive."""
    for c in range(ord(c1), ord(c2)+1):
        yield chr(c)

然后:

for c in char_range('a', 'z'):
    print(c)

9
美丽!对于要复制此文件的任何人,请记住,range(1,3)会迭代值1和2(而不是三个),但是char_range('a','c')会迭代'a','b'和'C'!
vicmortelmans

您也可以添加可选步骤arg:def char_range(c1, c2, step=1)...ord(c1), ord(c2)+1, step
wjandrea

@wjandrea,对于负面步骤并不太有用,例如,char_range('g','a',-1)给出['g', 'f', 'e', 'd', 'c']
alancalvitti

@alan不错!看来这是+1的错误ord(c2)。因此,请替换ord(c2)+1ord(c2) + (1 if step > 0 else -1)。尽管为了清楚起见,您可能希望将其排除在外range()
wjandrea

1
这样做的问题是,要生成az,您将需要知道哪个字符在z之后。不太舒服。最好避免使用名称“ range”(改用closedrange或inclusiverange?)
Camion

91
import string
for char in string.ascii_lowercase:
    print char

有关其他可能性,请参见字符串常量,包括大写字母,数字,与语言环境相关的字符,您可以将string.ascii_uppercase + string.ascii_lowercase所有这些字符连接在一起,就像您希望将多个字符集中在一起一样。


26

您必须将字符转换为数字,然后再次返回。

for c in xrange(ord('a'), ord('z')+1):
    print chr(c) # resp. print unicode(c)

为了美观和可读性,您可以将其包装在生成器中:

def character_range(a, b, inclusive=False):
    back = chr
    if isinstance(a,unicode) or isinstance(b,unicode):
        back = unicode
    for c in xrange(ord(a), ord(b) + int(bool(inclusive)))
        yield back(c)

for c in character_range('a', 'z', inclusive=True):
    print(chr(c))

可以使用inclusive=False(默认)调用此生成器以模仿Python的常规行为以排除end元素,或者使用inclusive=True(默认)调用此生成器以包括它。因此,使用默认设置时inclusive=False'a', 'z'将跨范围从ay,不包括z

如果unicode中的任何一个为unicode ab则以unicode返回结果,否则使用chr

当前(可能)仅适用于Py2。


3
您可以将其隐藏在生成器中:请参阅我的答案。
Ned Batchelder

2
您的意思是说,面对ord和chr时,您会更喜欢它吗?而且,如果您不得不多次执行此操作,那么您需要在每个位置复制它吗?奇怪..
Ned Batchelder

所以我最好说“看起来更好”,而不是“看起来更好”。
glglgl 2011年

12

这里还有其他很好的答案(我个人可能会使用string.lowercase),但是出于完整性考虑,您可以在小写的ascii值上使用map()chr()

for c in map(chr, xrange(97, 123)):
   print c

9

如果您有一小段固定的字符列表,只需使用Python对字符串的处理作为列表。

for x in 'abcd':
    print x

要么

[x for x in 'abcd']

6

我喜欢这样的方法:

base64chars = list(chars('AZ', 'az', '09', '++', '//'))

当然可以更加舒适地实现它,但是它既快速又容易并且可读性强。

Python 3

发电机版本:

def chars(*args):
    for a in args:
        for i in range(ord(a[0]), ord(a[1])+1):
            yield chr(i)

或者,如果您喜欢列表理解:

def chars(*args):
    return [chr(i) for a in args for i in range(ord(a[0]), ord(a[1])+1)]

第一个产量:

print(chars('ĀĈ'))
<generator object chars at 0x7efcb4e72308>
print(list(chars('ĀĈ')))
['Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ']

而第二个产量:

print(chars('ĀĈ'))
['Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ']

真的很方便:

base64chars = list(chars('AZ', 'az', '09', '++', '//'))
for a in base64chars:
   print(repr(a),end='')
print('')
for a in base64chars:
   print(repr(a),end=' ')

输出

'A''B''C''D''E''F''G''H''I''J''K''L''M''N''O''P''Q''R''S''T''U''V''W''X''Y''Z''a''b''c''d''e''f''g''h''i''j''k''l''m''n''o''p''q''r''s''t''u''v''w''x''y''z''0''1''2''3''4''5''6''7''8''9''+''/'
'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '+' '/' 

为什么list()呢?不带base64chars可能成为生成器(取决于您选择的实现),因此只能在第一个循环中使用。

Python 2

类似的内容可以用Python 2存档。但是,如果您也想支持Unicode,则要复杂得多。为了鼓励您停止使用Python 2而转而使用Python 3,在这里我不介意提供Python 2解决方案;)

今天尝试避免将Python 2用于新项目。另外,在扩展旧项目之前,请先尝试将其移植到Python 3中-从长远来看,这是值得的!

在Python 2中正确处理Unicode极其复杂,如果从一开始就没有内置Unicode支持,则几乎不可能将其添加到Python 2项目中。

提示如何将其反向移植到Python 2:

  • 使用xrange代替range
  • 创建unicodes用于处理Unicode的第二个函数(?):
    • 使用unichr而不是chr返回unicode代替str
    • 永远不要忘记输入unicode字符串args以使ord数组和下标正常工作

5
for character in map(   chr, xrange( ord('a'), ord('c')+1 )   ):
   print character

印刷品:

a
b
c

5
# generating 'a to z' small_chars.
small_chars = [chr(item) for item in range(ord('a'), ord('z')+1)]
# generating 'A to Z' upper chars.
upper_chars = [chr(item).upper() for item in range(ord('a'), ord('z')+1)]

3

受以上最高职位的启发,我想到了这个:

map(chr,range(ord('a'),ord('z')+1))                     

1

在这里使用@ ned-batchelder的答案,我正在对其进行一些修改 python3

def char_range(c1, c2):
    """Generates the characters from `c1` to `c2`, inclusive."""
    """Using range instead of xrange as xrange is deprecated in Python3""" 
    for c in range(ord(c1), ord(c2)+1):
        yield chr(c)

然后,与内德的答案相同:

for c in char_range('a', 'z'):
    print c

谢谢内德!


1

我有同样的需求,我用了这个:

chars = string.ascii_lowercase
range = list(chars)[chars.find('a'):chars.find('k')+1]

希望这对别人有帮助


这是一个好主意,对我的应用程序来说很优雅,例如:(for c in string.ascii_uppercase注意:OP的范围是“ bug”)。
Curt

0

使用“用于范围计数”和chr&ord:

print [chr(ord('a')+i) for i in range(ord('z')-ord('a'))]

0

使用清单理解:

for c in [chr(x) for x in range(ord('a'), ord('z'))]:
    print c

0

另一个选项(像范围一样操作-如果希望包含在内,则加1以停止)

>>> import string
>>> def crange(arg, *args):
...     """character range, crange(stop) or crange(start, stop[, step])"""
...     if len(args):
...         start = string.ascii_letters.index(arg)
...         stop = string.ascii_letters.index(args[0])
...     else:
...         start = string.ascii_letters.index('a')
...         stop = string.ascii_letters.index(arg)
...     step = 1 if len(args) < 2 else args[1]
...     for index in range(start, stop, step):
...         yield string.ascii_letters[index]
...
>>> [_ for _ in crange('d')]
['a', 'b', 'c']
>>>
>>> [_ for _ in crange('d', 'g')]
['d', 'e', 'f']
>>>
>>> [_ for _ in crange('d', 'v', 3)]
['d', 'g', 'j', 'm', 'p', 's']
>>>
>>> [_ for _ in crange('A', 'G')]
['A', 'B', 'C', 'D', 'E', 'F']

0

根据字符范围的复杂程度,使用正则表达式可能会很方便:

import re
import string

re.findall("[a-f]", string.printable)
# --> ['a', 'b', 'c', 'd', 'e', 'f']

re.findall("[n-qN-Q]", string.printable)
# --> ['n', 'o', 'p', 'q', 'N', 'O', 'P', 'Q']

这可以解决令人讨厌的问题,即偶然在ASCII表中的数字,大写和小写字母之间包含标点符号。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.