列表推导内部定义的变量是否会泄漏到封闭范围内?

时间:2015-04-24 09:36:06

标签: python python-3.x scope list-comprehension python-2.x

我无法找到定义此行为的任何地方:

if [x for x in [0, 1, -1] if x > 0]:
    val = x

这段代码有多安全?如果列表中的任何元素大于0,是否总是将val分配给列表中的最后一个元素?

2 个答案:

答案 0 :(得分:3)

在Python 2.x中,列表推导内部定义的变量会泄漏到它们的封闭范围内,所以是的,val将始终绑定到列表理解期间绑定到x的最后一个值(只要由于理解是一个非空的,因此" truthy",列表)。

但是,在Python 3.x中,情况不再是这样了:

>>> x = 'foo'
>>> if [x for x in [0, 1, -1] if x > 0]:
...     val = x
... 
>>> val
'foo'

行为(几乎没有)记录here

  

在Python 2.3及更高版本中,列表推导将其包含的每个for的控制变量“泄漏”到包含的范围中。但是,这种行为已被弃用,依赖它不会在Python 3中起作用。

...随着Python 3.x的变化记录here

  

[...] 请注意,列表推导具有不同的语义:它们更接近于list()构造函数内的生成器表达式的语法糖,特别是循环控制变量是不再泄露到周围的范围内。

看起来2.x的行为并不是任何人都特别自豪的事实,事实上Guido van Rossum将其称为“Python”之一#34;脏小秘密"'在blog post

答案 1 :(得分:-3)

这样不容易吗?

in_array(!null,$_FILES['field_name']['name'])