hun*_*nse 76 python list-comprehension generator python-2.7
如果我对列表推导做了些什么,它会写入一个局部变量:
i = 0
test = any([i == 2 for i in xrange(10)])
print i
Run Code Online (Sandbox Code Playgroud)
这打印"9".但是,如果我使用生成器,它不会写入局部变量:
i = 0
test = any(i == 2 for i in xrange(10))
print i
Run Code Online (Sandbox Code Playgroud)
这打印"0".
这种差异有什么好的理由吗?这是设计决策,还是生成器和列表推导的实现方式的随机副产品?就个人而言,如果列表推导没有写入局部变量,那对我来说似乎更好.
pok*_*oke 74
Python的创建者Guido van Rossum在撰写有关Python 3中统一构建的生成器表达式时提及了这一点:(强调我的)
我们还在Python 3中进行了另一项更改,以改进列表推导和生成器表达式之间的等效性.在Python 2中,列表推导将循环控制变量"泄漏"到周围的范围中:
Run Code Online (Sandbox Code Playgroud)x = 'before' a = [x for x in 1, 2, 3] print x # this prints '3', not 'before'这是列表推导的原始实现的工件; 多年来它一直是Python"肮脏的小秘密"之一.它起初是一种故意的妥协,使列表理解能够快速地进行,虽然它对于初学者来说不是常见的陷阱,但它偶尔会刺激人们.对于生成器表达式,我们不能这样做.生成器表达式使用生成器实现,生成器的执行需要单独的执行帧.因此,生成器表达式(特别是如果它们在短序列上迭代)的效率低于列表推导.
但是,在Python 3中,我们决定使用与生成器表达式相同的实现策略来修复列表推导的"脏小秘密".因此,在Python 3中,上面的例子(修改后使用print(x):-)将打印'before',证明列表理解中的'x'暂时阴影但不覆盖周围的'x'范围.
所以在Python 3中你不会再看到这种情况了.
有趣的是,Python 2中的字典理解也没有这样做; 这主要是因为dict理解是从Python 3向后移植的,因此已经有了修复.
还有一些其他问题也涵盖了这个主题,但我确定你在搜索主题时已经看过那些,对吧?;)
就个人而言,如果列表推导没有写入局部变量,那对我来说似乎更好.
你是对的.这在Python 3.x中得到修复.该行为在2.x中保持不变,因此它不会影响(ab)使用此漏洞的现有代码.
| 归档时间: |
|
| 查看次数: |
2331 次 |
| 最近记录: |