从字符列表生成字符串

Generating strings from a list of characters

我有以下信件:

Letters = ["a", "b", "c", "d", "e"]

我想要编写一个生成器函数,该函数将创建可以通过采用任何字母的组合形成的字符串,最好按照某种确定的顺序,例如从最小到最大。

例如,如果我 运行 生成器 20 次,我会得到

 a
 b
 c
 d
 e

aa
ab
ac
ad
ae

ba
bb
bc
bd
be

ca
cb
cc
cd
ce

da

我将如何编写这个生成器?

使用 itertools 库中的组合函数。有置换和无置换两种组合

for item in itertools.combinations(Letters, 2):
    print("".join(item))

https://docs.python.org/3.4/library/itertools.html

使用itertools.product():

from itertools import product, imap
letters = ["a", "b", "c", "d", "e"]
letters += imap(''.join, product(letters, repeat=2))
print letters

['a', 'b', 'c', 'd', 'e', 'aa', 'ab', 'ac', 'ad', 'ae', 'ba', 'bb', 'bc', 'bd', 'be', 'ca', 'cb', 'cc', 'cd', 'ce', 'da', 'db', 'dc', 'dd', 'de', 'ea', 'eb', 'ec', 'ed', 'ee']

我使用递归生成器函数(没有 itertools)

Letters = ["a", "b", "c", "d", "e"]

def my_generator(list, first=""):
  for letter in list:
    yield first + letter
  my_generators = []
  for letter in list:
    my_generators.append(my_generator(list, first + letter))
  i = 0
  while True:
    for j in xrange(len(list)**(i/len(list)+1)):
      yield next(my_generators[i%len(list)])
    i+=1

gen = my_generator(Letters)
[next(gen) for c in xrange(160)]

你得到

['a', 'b', 'c', 'd', 'e', 'aa', 'ab', 'ac', 'ad', 'ae', 'ba', 'bb',
'bc', 'bd', 'be', 'ca', 'cb', 'cc', 'cd', 'ce', 'da', 'db', 'dc',
'dd', 'de', 'ea', 'eb', 'ec', 'ed', 'ee', 'aaa', 'aab', 'aac', 'aad',
'aae', 'aba', 'abb', 'abc', 'abd', 'abe', 'aca', 'acb', 'acc', 'acd',
'ace', 'ada', 'adb', 'adc', 'add', 'ade', 'aea', 'aeb', 'aec', 'aed', 
'aee', 'baa', 'bab', 'bac', 'bad', 'bae', 'bba', 'bbb', 'bbc', 'bbd',
'bbe', 'bca', 'bcb', 'bcc', 'bcd', 'bce', 'bda', 'bdb', 'bdc', 'bdd',
'bde', 'bea', 'beb', 'bec', 'bed', 'bee', 'caa', 'cab', 'cac', 'cad',
'cae', 'cba', 'cbb', 'cbc', 'cbd', 'cbe', 'cca', 'ccb', 'ccc', 'ccd',
'cce', 'cda', 'cdb', 'cdc', 'cdd', 'cde', 'cea', 'ceb', 'cec', 'ced',
'cee', 'daa', 'dab', 'dac', 'dad', 'dae', 'dba', 'dbb', 'dbc', 'dbd',
'dbe', 'dca', 'dcb', 'dcc', 'dcd', 'dce', 'dda', 'ddb', 'ddc', 'ddd',
'dde', 'dea', 'deb', 'dec', 'ded', 'dee', 'eaa', 'eab', 'eac', 'ead',
'eae', 'eba', 'ebb', 'ebc', 'ebd', 'ebe', 'eca', 'ecb', 'ecc', 'ecd', 
'ece', 'eda', 'edb', 'edc', 'edd', 'ede', 'eea', 'eeb', 'eec', 'eed',
'eee', 'aaaa', 'aaab', 'aaac', 'aaad', 'aaae']

生成器函数:

from itertools import *

def wordgen(letters):
    for n in count(1):
        yield from map(''.join, product(letters, repeat=n))

用法:

for word in wordgen('abcde'):
    print(word)

输出:

a
b
c
d
e
aa
ab
ac
ad
ae
ba
bb
bc
bd
be
ca
...

不使用 itertools 的自制替代方案:

def wordgen(letters):
    yield from letters
    for word in wordgen(letters):
        for letter in letters:
            yield word + letter

高尔夫版(诚然以空字符串开头):

def w(s):yield'';yield from(w+c for w in w(s)for c in s)