Issue
I can't find anywhere that defines this behaviour:
if [x for x in [0, 1, -1] if x > 0]:
val = x
How safe is this code? Will val
always be assigned to the last element in the list if any element in the list is greater than 0?
Solution
In Python 2.x, variables defined inside list comprehensions leak into their enclosing scope, so yes, val
will always be bound to the last value bound to x
during the list comprehension (as long as the result of the comprehension is a non-empty, and therefore "truthy", list).
However, in Python 3.x, this is no longer the case:
>>> x = 'foo'
>>> if [x for x in [0, 1, -1] if x > 0]:
... val = x
...
>>> val
'foo'
The behaviour is (just barely) documented here:
In Python 2.3 and later releases, a list comprehension “leaks” the control variables of each
for
it contains into the containing scope. However, this behavior is deprecated, and relying on it will not work in Python 3.
... with the change in Python 3.x documented here:
[...] note that list comprehensions have different semantics: they are closer to syntactic sugar for a generator expression inside a
list()
constructor, and in particular the loop control variables are no longer leaked into the surrounding scope.
It would appear that the 2.x behaviour wasn't something anyone was particularly proud of, and in fact Guido van Rossum refers to it as 'one of Python's "dirty little secrets"' in a blog post.
Answered By - Zero Piraeus
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.