按顺序生成字母数字字符串

8 投票
5 回答
11788 浏览
提问于 2025-04-17 00:01

我想创建一个循环,生成并打印字符串,要求如下:

  1. 只包含字母和数字:
  2. 数字0-9在字母A-Z之前,字母A-Z又在字母a-z之前,
  3. 字符串的长度最多为4个字符。

所以,它会打印:

  1. 从0到z的所有字符串
  2. 然后是从00到zz的字符串
  3. 接着是从000到zzz的字符串
  4. 最后是从0000到zzzz的字符串

然后就停止了。

5 个回答

0

我不太喜欢之前提到的用 product 的答案,因为在查看 Python 文档中的实现时,发现它会先把所有内容放到内存中的一个列表里,然后再开始返回结果。

这样做对你的情况很糟糕,因为正如 agf 自己所说,这里的排列组合数量非常庞大(超过一百万)。为了应对这种情况,yield 语句被创造出来——这样就可以动态生成巨大的列表,而不是一次性把它们都放到内存里(我也不喜欢浪费内存的 range,因为 xrange 完全可以用)。

我会选择这样的解决方案:

def generate(chars, length, prefix = None):
    if length < 1:
        return
    if not prefix:
        prefix = ''
    for char in chars:
        permutation = prefix + char
        if length == 1:
            yield permutation
        else:
            for sub_permutation in generate(chars, length - 1, prefix = permutation):
                yield sub_permutation

这样做的话,内存中只会有一个深度为 "n" 的递归栈,其中 "n" 是你的排列组合的长度(在这个例子中是 4),每次只返回一个元素。

chars 是可供选择的字符集合,长度是 4,使用方式和 product 类似,只不过在运行时不会把整个列表都放到内存里。

1
from string import digits, ascii_uppercase, ascii_lowercase
from itertools import product
chars = digits + ascii_uppercase + ascii_lowercase

def give_me_next(lst):
        lst = lst[::-1]
        change_next = False
        change = True
        n = 0
        for x in lst:
                if change_next == True:
                        change_next = False
                        pos = chars.find(x)
                        try:
                                a =  chars[pos+1]
                                lst = list(lst)
                                lst[n] = a
                                lst = "".join(lst)
                                x = a
                        except:
                                lst = list(lst)
                                lst[n] = '0'
                                lst = "".join(lst)
                                change_next = True
                                x = '0'

                pos = chars.find(x)
                try:
                        a =  chars[pos+1]
                        if change == True:
                                lst = list(lst)
                                lst[n] = a
                                lst = "".join(lst)
                                change = False
                except:
                        lst = list(lst)
                        lst[n] = '0'
                        lst = "".join(lst)
                        change_next = True

                n = n + 1

        lst = lst[::-1]
        return lst

a=  give_me_next('zzzzz')
while True:
        a =  give_me_next(a)
        print a

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

24
from string import digits, ascii_uppercase, ascii_lowercase
from itertools import product

chars = digits + ascii_uppercase + ascii_lowercase

for n in range(1, 4 + 1):
    for comb in product(chars, repeat=n):
        print ''.join(comb)

首先,这段代码会把所有的数字、大写字母和小写字母组合成一个字符串。

接着,对于长度从1到4的每一种情况,它会打印出所有可能的组合,这些组合由这些数字和字母组成。

要记住,这样的组合数量非常庞大——计算方式是62的4次方加上62的3次方,再加上62的2次方,最后加上62。

撰写回答