2015-05-05 4 views
0

У меня есть следующие буквы:Генерация строки из списка символов

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 

Как бы написать этот генератор?

ответ

1

Используйте функции комбинаций из библиотеки itertools. Там в обе комбинации с заменой и без замены

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

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

+0

Я попытался 'combinations' , затем посмотрел на остальную часть модуля и обнаружил, что 'перестановки' были более подходящими для того, что мне было нужно. Благодаря! – MxyL

1

Использование itertools.product():

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

[ 'а', 'б', 'с', '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 ']

0

Я использую рекурсивную функцию генератора (без 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'] 
+0

этот код имеет проблему: я должен использовать переменные 'my_generators' и генераторы хранения (> RAM) –

+0

Спасибо, вы мотивировали меня написать собственный генератор без использования itertools. Я добавил его к моему ответу. –

2

функция генератора:

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) 
+0

Не загромождайте пространство имен с помощью '' from module import * ''. Импортируйте отдельные функции, которые вам нужны, или просто используйте '' import module'' и точечную нотацию. – pzp

+0

@pzp Я не пишу учебник о том, как импортировать. Я пишу mcve ответ на вопрос. Тем не менее, я новичок здесь, поэтому, если вы покажете мне руководство сообщества, говоря, что я должен делать это по-другому, тогда я, скорее всего, буду. –

+0

'yield from'is python 3? –

Смежные вопросы