2016-08-24 8 views
3

Я написал функцию для создания двоичных строк, начиная с заданного списка s (все двоичные строки, которые заканчиваются в один из s элементов):выражение Генератор делает двоичная строка генератор замерзнуть навсегда

def binary_strings(s): 
    yield from s 
    while True: 
     s = [b + x for x in s for b in "01"] 
     yield from s 

Он работает, как вы Как видно из вывода:

>>> for i in binary_strings(["10", "01"]): print(i) 

10 
01 
010 
110 
001 
101 
0010 
1010 
0110 
1110 
0001 
1001 
0101 
1101 
00010 
10010 
01010 
11010 
00110 
10110 
01110 
11110 
00001 
10001 
01001 
11001 
00101 
10101 
01101 
11101 
000010 
100010 
... # Output is infinite so I must truncate it. 

Теперь я могу изменить s и использовать выражение генератор для него вместо списка:

def binary_strings(s): 
    yield from s 
    while True: 
     s = (b + x for x in s for b in "01") 
     yield from s 

Теперь выполнение резко останавливается после исчерпания возможностей 3 длины:

>>> for i in binary_strings(["10","01"]): print(i) 

10 
01 
010 
110 
001 
101 
# Output is not truncated, the function freezes at this points 
# and yield no more output 

Я ожидал, что вторая версия работать точно так же, как первый, потому что я никогда не использую методы списка на s и я просто перебирать это, почему не вторая версия работает?

ответ

1

Я нашел ответ, линия yield from s была изнурительным генератор так линий yield from s давали из пустого генератора (осмыслению перед выходами порожних как s пусто), следовательно, freezeing навсегда.

Список может быть повторен многократно, поэтому эта проблема не появляется.

Проблема появляется только после итерации, потому что в начале s является списком и становится генератором впоследствии.

+1

Да, но вы получите неправильный порядок, генератор исчерпан в 'yield from s' при первом входе в цикл while – Copperfield

+0

@Copperfield Фактически' yield from' в цикле выполняется только один раз, спасибо для уточнения – Caridorc