疯狂的Python-06(时间的误会)
2018-09-08 本文已影响1人
景行1023
一些有趣的鲜为人知的Python特性集合
无论你是Python新手还是Python老手,我相信,这个系列的文章都会让你获益良多!
阅读此系列任何文章前请务必观看:疯狂的Python-目录大纲
▶ 时间的误会
1.
array = [1, 8, 15]
g = (x for x in array if array.count(x) > 0)
array = [2, 8, 22]
Output:
>>> print(list(g))
[8]
2.
array_1 = [1,2,3,4]
g1 = (x for x in array_1)
array_1 = [1,2,3,4,5]
array_2 = [1,2,3,4]
g2 = (x for x in array_2)
array_2[:] = [1,2,3,4,5]
Output:
>>> print(list(g1))
[1,2,3,4]
>>> print(list(g2))
[1,2,3,4,5]
:bulb: 解释
- 在生成器表达式中,
in
语句会在声明阶段求值,但是条件判断语句(在这里是array.count(x) > 0
)会在真正的运行阶段(runtime)求值。 - 在生成器运行之前,
array
已经被重新赋值为[2, 8, 22]
了,所以这个时候再用count
函数判断2
,8
,22
在原列表中的数量,只有8
是数量大于0
的,所以最后这个生成器只返回了一个8
是符合条件的。 - 在第二部分中,
g1
,g2
输出结果不同,是因为对array_1
和array_2
的赋值方法不同导致的。 - 在第一个例子中,
array_1
绑定了一个新的列表对象[1,2,3,4,5]
(可以理解成array_1
的指针指向了一个新的内存地址),而且在这之前,in
语句已经在声明时就为g1
绑定好了旧的列表对象[1,2,3,4]
(这个就对象也没有随着新对象的赋值而销毁)。所以这时候g1
和array_1
是指向不同的对象地址的。 - 在第二个例子中,由于切片化的赋值,
array_2
并没有绑定(指向)新对象,而是将旧的对象[1,2,3,4]
更新(也就是说旧对象的内存地址被新对象占用了)成了新的对象[1,2,3,4,5]
。所以,g2
和array_2
依旧同时指向一个地址,所以都更新成了新对象[1,2,3,4,5]
。