Explanation of this Python language feature? [x for x in x for x in x] (to flatten a nested list)

Chris Angelico rosuav at gmail.com
Fri Mar 21 22:41:27 EDT 2014


On Sat, Mar 22, 2014 at 1:06 PM, Rustom Mody <rustompmody at gmail.com> wrote:
> Two: A comprehension variable is not bound but reassigned across the
> comprehension. This problem remains in python3 and causes weird behavior when
> lambdas are put in a comprehension
>
>>>> fl = [lambda y : x+y for x in [1,2,3]]
>>>> [fl[i](2) for i in [0,1,2]]
> [5, 5, 5]

To clarify, what you're saying here is that x in the first
comprehension's closures should be bound to separate values for x,
yes?

I'm not sure how that ought to be done. Having closures that can
reference and modify each other's variables is important.

def func_pair():
    x = 0
    def inc():
        nonlocal x; x+=1
        return x
    def dec():
        nonlocal x; x-=1
        return x
    return inc, dec

fooup, foodn = func_pair()
barup, bardn = func_pair()
>>> fooup(), fooup(), fooup(), foodn()
(1, 2, 3, 2)
>>> barup(), barup(), bardn(), bardn()
(1, 2, 1, 0)

Those functions are fundamentally linked. Very useful with callbacks.
A nice alternative to doing everything with bound methods.

So if that's not going to be broken, how is this fundamentally different?

def func_loop():
    for x in 1,2,3:
        yield (lambda: x)

one, two, three = func_loop()
one(), one(), two(), two(), three(), three()

This one does NOT work the way the names imply, and I can see that
you'd like to fix it. But I can't pinpoint a significant difference
between them. How do you distinguish?

ChrisA



More information about the Python-list mailing list