Python中等价于perl中"a".."azc"的是什么?

7
在Perl中,要获取从"a"到"azc"的所有字符串列表,唯一需要做的就是使用范围操作符:
perl -le 'print "a".."azc"'

我需要的是一个字符串列表:

["a", "b", ..., "z", "aa", ..., "az" ,"ba", ..., "azc"]

我可以使用ordchr来循环获取从"a"到"z"的字符,这很简单:

>>> [chr(c) for c in range(ord("a"), ord("z") + 1)]
['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']

但对于我的情况来说,这有点复杂。
谢谢任何帮助!
6个回答

5

生成器版本:

from string import ascii_lowercase
from itertools import product

def letterrange(last):
    for k in range(len(last)):
        for x in product(ascii_lowercase, repeat=k+1):
            result = ''.join(x)
            yield result
            if result == last:
                return

编辑:@ihightower在评论中问道:

如果我想从“b”打印到“azc”,我该怎么办?

所以您想从除'a'之外的其他字符开始。 只需丢弃起始值之前的任何内容:

def letterrange(first, last):
    for k in range(len(last)):
        for x in product(ascii_lowercase, repeat=k+1):
            result = ''.join(x)
            if first:
                if first != result:
                    continue
                else:
                    first = None
            yield result
            if result == last:
                return

1
是的!绝对不错(我不能投票,因为我的声望只有11分,但听起来很正确!) - Alexis Métaireau
可能是个好答案...但是,怎么使用呢?作为一个新手,如果我想从“b”打印到“azc”,我不知道该怎么做。这个函数可能很好...但是作为一个初学者,我不知道如何使用它来完成实际的工作和打印。 - ihightower

4

一个基于迭代器的建议:

import string
import itertools

def string_range(letters=string.ascii_lowercase, start="a", end="z"):
    return itertools.takewhile(end.__ne__, itertools.dropwhile(start.__ne__, (x for i in itertools.count(1) for x in itertools.imap("".join, itertools.product(letters, repeat=i)))))

print list(string_range(end="azc"))

2
使用itertools中的product函数和string模块中的ascii_letters。
from string import ascii_letters
from itertools import product

if __name__ == '__main__':
    values = []
    for i in xrange(1, 4):
        values += [''.join(x) for x in product(ascii_letters[:26], repeat=i)]

    print values

应该是ascii_lowercase,而你还没有考虑停在“azc”。 - Matthew Flaschen
嗯,谢谢。在这里我可以得到一个从a到zzz的字符串列表。因此,我将进行第二次循环,将第一次循环中的项目复制到第二个循环中,并且在遇到"end"字符串时停止。我将用完整的代码示例回答我的问题。非常感谢! - Alexis Métaireau

1
这里有一种更好的方法,尽管您需要一个转换函数:
for i in xrange(int('a', 36), int('azd', 36)):
    if base36encode(i).isalpha():
        print base36encode(i, lower=True)

这是您的函数(感谢维基百科):

def base36encode(number, alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', lower=False):
    '''
    Convert positive integer to a base36 string.
    '''
    if lower:
        alphabet = alphabet.lower()
    if not isinstance(number, (int, long)):
        raise TypeError('number must be an integer')
    if number < 0:
        raise ValueError('number must be positive')

    # Special case for small numbers
    if number < 36:
        return alphabet[number]

    base36 = ''
    while number != 0:
        number, i = divmod(number, 36)
        base36 = alphabet[i] + base36

    return base36

我添加了小写转换选项,以防您需要。


1

我将被接受的答案概括,以便能够开始中间并使用小写字母以外的其他内容:

from string import ascii_lowercase, ascii_uppercase
from itertools import product

def letter_range(first, last, letters=ascii_lowercase):
    for k in range(len(first), len(last)):
        for x in product(letters, repeat=k+1):
            result = ''.join(x)
            if len(x) != len(first) or result >= first:
                yield result
                if result == last:
                    return
print list(letter_range('a', 'zzz'))
print list(letter_range('BA', 'DZA', ascii_uppercase))

0
def strrange(end):
    values = []
    for i in range(1, len(end) + 1):
        values += [''.join(x) for x in product(ascii_lowercase, repeat=i)]
    return values[:values.index(end) + 1]

дё»иҰҒй—®йўҳеҰӮдёӢпјҡ1пјүдҪҝз”Ё xrange иҖҢдёҚжҳҜ rangeгҖӮз”ұдәҺ range жҳҜз”ҹжҲҗеҷЁдё”дёҚдјҡйў„е…Ҳз”ҹжҲҗз»“жһңеҲ—иЎЁпјҢеӣ жӯӨ xrange дёҚеҶҚе…·жңүд»»дҪ•дјҳеҠҝгҖӮ еӣ жӯӨпјҢxrange е·Іиў«ејғз”ЁпјҢиҖҢдё”еңЁ Python 3 дёӯз”ҡиҮідёҚеӯҳеңЁгҖӮ2пјүд»Һ values жһ„йҖ  endvaluesпјҢеҪ“жӮЁеҸҜд»ҘдҪҝз”Ё list.index() е’ҢеҲҮзүҮж“ҚдҪңгҖӮ3пјүиҝҷдёҚжҳҜжӮЁеңЁ SO дёҠж Үи®°й—®йўҳдёәе·Іеӣһзӯ”зҡ„ж–№жі•гҖӮ - Mike DeSimone
2
@Mike,xrange在Python 2.7中仍然是必需的,这个版本发布不到两周。range仍然返回一个列表。 - Matthew Flaschen
我已经更新了这个程序,使用了切片和索引(index())函数。同时也删除了包装文本。 - Alexis Métaireau

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