2011-08-20 79 views
5

我试图创建一个循环来生成并打印字符串如下:生成字母数字串顺序

  1. 字母数字字符只有:
  2. 0-9 AZ之前,这是AZ之前,
  3. 长度最多可达4个字符。

所以,它会打印:

  1. 所有字符串从0-Z
  2. 然后从00-ZZ
  3. 然后从000-ZZZ
  4. 然后从0000-ZZZZ

然后停止。

+0

这太难理解你的问题了...... a07z会是一个合法的字符串吗? – immortal

+0

是的。所有字母数字字符串长度1-4是合法的 – joseph

+0

所以当你说0-9在A-Z之前时,你的意思是0000应该在A000之前? – immortal

回答

17
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

+0

这是一个很酷的解决方案。另外一件很酷的事情就是让它成为一个发生器,而不是直接打印字符串。 – Drekembe

+0

我知道这是一大堆组合,我主要是为了测试目的而做的。我把它缩小为3个字符而不是4个 – joseph

+0

是的,他说他想要一个“打印字符串的循环”,这就是我给他的。 – agf

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,使用与产品非常相似,只是它在运行时不会跨越整个内存列表。

+2

它在产品描述中说 - “除了实际的实现不会在内存中建立中间结果之外,这个函数与下面的代码是等价的:”itertools中的所有工具都是这样工作的,模块的全部用途。 – agf

+0

此外,调用范围(5)与xrange相比,浪费是一个有点拉伸... – hop

+0

我认为,对于非常小的范围,“范围”实际上比'xrange'更浪费。 – agf

0

我今天就编码了。它正是你想要的以及更多。它也可以扩展

def lastCase (lst): 
    for i in range(0, len(lst)): 
     if (lst[i] != '_'): 
      return False 
    return True 


l = [''] * 4 #change size here if needed. I used 4 
l[0] = '0' 
index = 0 

while (not lastCase(l)): 

    if (ord(l[index]) > ord('_')): 
     l[index] = '0' 
     index += 1 
     while(l[index] == '_'): 
      l[index] = '0' 
      index += 1 
     if (l[index] == ''): 
      l[index] = '0' 

    #print or process generated string 
    print(''.join(l)) 

    l[index] = chr(ord(l[index]) +1) 

    if (ord(l[index]) > ord('9') and ord(l[index]) < ord('A')): 
     l[index] = 'A' 
    elif (ord(l[index]) > ord('Z') and ord(l[index]) < ord('_') ): 
     l[index] = '_' 

    index = 0 

print (''.join(l))