Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generator expression makes binary string generator freeze forever

I have written a function to generate binary strings starting from a given list s (all binary strings that end in one of s items):

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

It works as you can see from the output:

>>> 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.

Now I modify s and use a generator expression for it instead of a list:

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

Now the execution abruptly stops after exhausting the 3-length possibilities:

>>> 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

I expected the second version to work just as well as the first because I never use list methods on s and I just iterate through it, why isn't the second version working?

like image 689
Caridorc Avatar asked Dec 08 '25 06:12

Caridorc


1 Answers

I found the answer, the line yield from s was exhausting the generator so the line yield from s yielded from an empty generator (the comprehension before yields empty as s is empty) hence freezeing forever.

A list instead can be iterated arbitrarly many times so this problem does not appear.

The problem appears only after an iteration because at the start s is a list and becomes a generator afterwards.

like image 165
Caridorc Avatar answered Dec 09 '25 18:12

Caridorc