2015-02-23 45 views
2
def permutations(iterable, r=None): 
    # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC 
    # permutations(range(3)) --> 012 021 102 120 201 210 
    pool = tuple(iterable) 
    n = len(pool) 
    r = n if r is None else r 
    if r > n: 
     return 
    indices = list(range(n)) 
    cycles = list(range(n, n-r, -1)) 
    yield tuple(pool[i] for i in indices[:r]) 
    while n: 
     for i in reversed(range(r)): 
      cycles[i] -= 1 
      if cycles[i] == 0: 
       indices[i:] = indices[i+1:] + indices[i:i+1] 
       cycles[i] = n - i 
      else: 
       j = cycles[i] 
       indices[i], indices[-j] = indices[-j], indices[i] 
       yield tuple(pool[i] for i in indices[:r]) 
       break 
     else: 
      return 

got = permutations(getAllTheLetters(),4) 
cnt = 0 
for i in got: 
    cnt += 1 
    print ''.join(i) 

print cnt 

以上犯規給予 'ZZZZ' 或 'ZZZ'
我需要低於它給出了類似: A,B,C,d .. AA ,ab,ac,.. aaa,aab ...蟒蛇:得到所有可能的字母達到一定長度

但do_perm()是硬編碼循環四次,我不想做。

def getAllTheLetters(begin='a', end='z'): 
    beginNum = ord(begin) 
    endNum = ord(end) 
    yield '' 
    for number in xrange(beginNum, endNum+1): 
     yield chr(number) 

def do_perm(l): 
    s = set() 
    for a in getAllTheLetters(): 
     for b in getAllTheLetters(): 
      for c in getAllTheLetters(): 
       for d in getAllTheLetters(): 
        to_add = "%s%s%s%s" % (a,b,c,d) 
        if to_add != "": 
         s.add(to_add) 

    return s 

got = do_perm(1) 
cnt = 0 
for i in sorted(got): 
    cnt +=1 
    print i 
print cnt 
+0

你想'itertools.combinations_with_replacement',而不是'itertools.permutations'。 – 2015-02-23 02:55:26

回答

4

您可以簡單地使用itertools.product,這樣

from itertools import product 

def get_strings(letters, max_length): 
    for i in range(1, max_length + 1): 
     for value in product(letters, repeat=i): 
      yield "".join(value) 

當你調用它像這樣

print(list(get_strings("ab", 2))) 

你會得到

['a', 'b', 'aa', 'ab', 'ba', 'bb'] 

如果你想從0123獲取所有值到z,你可以調用get_strings,這樣

from string import ascii_lowercase 
print(list(get_strings(ascii_lowercase, 4))) 

注:這將創造大量串中的地獄,讓你的機器可能會停止響應。如果您只是想遍歷字符串,請使用for循環,並使用get_strings(如下所示),並且不要創建列表。

for current_string in get_strings(ascii_lowercase, 4): 
    # Process the current_string