生成器 执行时机差异

2020-07-16 14:56:29

请用微信扫描二维码

请用微信扫码分享

❤️

一、
>>> array = [1, 3, 9]
>>> g = (i for i in array if array.count(i) > 0)
>>> array = [2, 3, 10]
>>> print(list(g))
[3]

为什么 g 是 [3]呢?明明array里面3个元素都符合判定条件。

因为:在生成器表达式中, in 子句在声明时执行, 而 if 字句则是在运行时执行。

所以:在运行前, array 已经被重新赋值为 [2, 3, 10], 运行时 if 后面的 array.count 中 array 的值就已经是[2, 3, 10] , 所以1, 3和9 只有count(3) > 0,所以生成器只会生成 [3]。

二、
>>> array_1 = [1, 2, 3, 4]
>>> g1 = [i for i in array_1]
>>> array_1 = [1, 2, 3, 4, 5]
>>> print(g1)
[1, 2, 3, 4]

这种情况也是符合上面原理,

array_1 被绑定到新对象 [1,2,3,4,5], 因为 in 子句是在声明时被执行的,

所以它仍然引用旧对象 [1,2,3,4] (并没有被销毁).

三、
>>> array_2 = [1,2,3,4]
>>> g2 = [i for i in array_2]
>>> array_2[:] = [1,2,3,4,5]
>>> print(g2)
[1, 2, 3, 4, 5]

这里是对 array_2 的切片赋值为[1, 2, 3, 4, 5],

所以同时也将array_2就对象[1, 2, 3, 4]原地更新为[1, 2, 3, 4, 5]。

因此g2和array_2仍然应用同一个对象(已更新为[1, 2, 3, 4, 5])

四、
>>> g = [i for i in array if array.count(i) > 0]
>>> array = [2, 3, 10]
>>> print(g)
[1, 3, 9]

这里我就没搞懂了,这和第一种情况是类似的啊,只是换成了列表生成式,就不一样了。

感觉python的版本更迭还是不太稳定的