List comp bug?
I seem to have stumbled across a problem with list comprehensions (or perhaps it's a misunderstanding on my part) [f() for f in [lambda: t for t in ((1, 2), (3, 4))]] is giving me [(3, 4), (3, 4)] The equivalent using a generator expression: [f() for f in (lambda: t for t in ((1, 2), (3, 4)))] is giving me [(1, 2), (3, 4)] as expected. Is this a known bug? I'm using Python 2.4.3 Thanks James -- http://mail.python.org/mailman/listinfo/python-list
Re: List comp bug?
[EMAIL PROTECTED] writes: I seem to have stumbled across a problem with list comprehensions (or perhaps it's a misunderstanding on my part) [f() for f in [lambda: t for t in ((1, 2), (3, 4))]] List comprehensions are syntactic sugar for for loops. The thing to notice is that in lambda: t, t is unbound. It's not the same as the loop index inside the list comp. Try: [f() for f in [lambda t=t: t for t in ((1, 2), (3, 4))]] -- http://mail.python.org/mailman/listinfo/python-list
Re: List comp bug?
[EMAIL PROTECTED] wrote: I seem to have stumbled across a problem with list comprehensions (or perhaps it's a misunderstanding on my part) [f() for f in [lambda: t for t in ((1, 2), (3, 4))]] is giving me [(3, 4), (3, 4)] The equivalent using a generator expression: [f() for f in (lambda: t for t in ((1, 2), (3, 4)))] is giving me [(1, 2), (3, 4)] as expected. Is this a known bug? no, it's not a bug, it's a consequence of the order in which things are done, and different visibility rules for the loop variables used in list comprehensions and generator expressions. both the inner loops generates lambda expressions that return the value of the t variable. for the list comprehension, t is an ordinary variable (part of the surrounding scope), and since the comprehension is completed before the resulting list is returned, all lambdas end up referring to the same t, which is set to the last value: x = [lambda: t for t in ((1, 2), (3, 4))] x [function lambda at 0x00A87AB0, function lambda at 0x00A876F0] x[0]() (3, 4) t = hello x[0]() 'hello' in contrast, the generator expression uses a local loop variable t, and only fetches one value from the target sequence for each iteration, so all lambdas will be bound to different objects. any special reason you need to write this kind of convoluted code, btw? /F -- http://mail.python.org/mailman/listinfo/python-list
Re: List comp bug?
[EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] [f() for f in [lambda: t for t in ((1, 2), (3, 4))]] is giving me [(3, 4), (3, 4)] The equivalent using a generator expression: List comps were originally designed to be equivalent to for loops with nested for loops and if blocks. Generator expressions are know to be slightly different and *not* exactly equivalent due to the new local namespace. [f() for f in (lambda: t for t in ((1, 2), (3, 4)))] is giving me [(1, 2), (3, 4)] Since, when there is a difference, as above, the genex behavior is more often the right or expected behavior (as above), Guido is considering making the diference go away in 3.0 by making [stuff] == list((stuff)) (ie, listcomp == list(genex)). Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list