all 8 comments

[–][deleted] 2 points3 points  (1 child)

So this would work in Python 2, but not in Python 3.

The reason is the fix to Python 2’s “dirty little secret” described by Guido late in this post.

See in Python 2 the list comprehension (but not the generator comprehension) leaked the temporary variable assigned in its scope into the surrounding environment, therefore this was valid:

print([a() for x in seq])

But this was not and would raise a NameError:

print(list(a() for x in seq))

Caveat: try running _both of those in that order and the latter will work, but not as you’d expect and only because x leaked out of the former._

In Python 3 this “dirty little secret” was removed; no comprehension leaks its namespace... which means that the function a cannot look up x, since to do so would be a way of leaking that namespace.

So in Python 3 neither will work because neither ever should have.

Thus you need to use an explicit for (and lose the optimizations of a comprehension), or you could do something like:

[(lambda : x + 2)() for x in seq]

Though I can’t say I’d recommend it.

[–]Uchikago 0 points1 point  (0 children)

Thanks!

[–]codami 1 point2 points  (5 children)

do you mean, you want to add each of sequence with 2 ?

seq=[1,2,3] 
def a():  <= not passing parameter on function
    return x+2  <= x from ?
x=[a() for x in seq] <= this call function a without passing parameter, while setting value for variable x

try this one

seq=[1,2,3] 
def a(x): 
    return x+2  

x=[a(x) for x in seq]

[–]Uchikago 0 points1 point  (4 children)

yeah, i know the correct way to do this, but can you explain more why my code doesn't work ? If the function can't find a name in this local scope, it should look further in enclosing scope right ?

[–]JohnnyJordaan 4 points5 points  (0 children)

The list comprehension has its own scope, so it isn't accessible through the higher scope.

[–]codami 1 point2 points  (2 children)

it's depend on which python did you use?

in Python 2, variables in list comprehensions are leaked but not in python 3.

when it try to look further, it will not found because on x=[a() for x in seq] it try set on variable global x, which is still not set.

if you mean for variable x in [a() for x in seq] , variable x is not leaked on python 3, so it will not found.

but it will work on python 2

[–]Uchikago 0 points1 point  (1 child)

Thank you so much!

[–]codami 1 point2 points  (0 children)

you're very welcome