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