Question for python experts: code does not work when called with generators

I have a small snippet that does not work inexplicably.
The goal is to generate all combinations of two or more sequences.
It works when called with lists, but when called with generators, it does not.

def comb(seqs):
    if seqs:
        for item in seqs[0]:
            for rest in comb(seqs[1:]):
                yield [item] + rest
    else:
        yield []

if __name__=="__main__":
    x=[1,2]
    y=[3,4]
    print list(comb([x,y])) # prints [[1, 3], [1, 4], [2, 3], [2, 4]]

    def gen1(): yield 1; yield 2
    def gen2(): yield 3; yield 4
    x=gen1()
    y=gen2()
    print list(comb([x,y])) # prints [[1, 3], [1, 4]  WHY ????
+3
source share
4 answers

The reason is that you can only iterate over the generator once. In line

for item in seqs[0]

When you go to the second element gen1, you make a recursive call to iterate over the elements gen2. The problem is that you have already done a repeat over gen2in the previous recursive call, so it will not give any elements.

+2

, , , .

comb , , , .

+7

Fix:

def comb(seqs):
    if seqs:
        inner = list(comb(seqs[1:]))        
        for item in seqs[0]:
            for rest in inner:
                yield [item] + rest
    else:
        yield []
+2
source

Take a look at itertools at docs.python.org , there you will probably find everything you need to create iterators for an efficient loop

0
source

All Articles