Generator oddity

Dave Angel davea at ieee.org
Fri May 1 10:25:23 EDT 2009


opstad at batnet.com wrote:
> I'm a little baffled by the inconsistency here. Anyone have any
> explanations?
>
>   
>>>> def gen():
>>>>         
> ...   yield 'a'
> ...   yield 'b'
> ...   yield 'c'
> ...
>   
>>>> [c1 + c2 for c1 in gen() for c2 in gen()]
>>>>         
> ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']
>
>   
>>>> list(c1 + c2 for c1 in gen() for c2 in gen())
>>>>         
> ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']
>
>   
>>>> it1 = gen()
>>>> it2 = gen()
>>>> list(c1 + c2 for c1 in it1 for c2 in it2)
>>>>         
> ['aa', 'ab', 'ac']
>
> Why does this last list only have three elements instead of nine?
>
>
>   
The problem is in it2, which is initialized only once.  Thus the second 
time you're going through the c2 loop, it doesn't have any more values.

If you need the indirection provided by those it1 and it2, you need to 
postpone the function evaluation, at least for it2.

I'd do
it1 = gen
it2 = gen

list(c1 + c2 for c1 in it1() for c2 in it2())
or more simply:
[c1 + c2 for c1 in it1() for c2 in it2()]







More information about the Python-list mailing list