疯狂的Python-06(时间的误会)

疯狂的Python-06(时间的误会)_第1张图片

一些有趣的鲜为人知的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_1array_2的赋值方法不同导致的。
  • 在第一个例子中, array_1绑定了一个新的列表对象[1,2,3,4,5](可以理解成array_1的指针指向了一个新的内存地址),而且在这之前,in语句已经在声明时就为g1绑定好了旧的列表对象[1,2,3,4](这个就对象也没有随着新对象的赋值而销毁)。所以这时候g1array_1是指向不同的对象地址的。
  • 在第二个例子中,由于切片化的赋值,array_2并没有绑定(指向)新对象,而是将旧的对象[1,2,3,4]更新(也就是说旧对象的内存地址被新对象占用了)成了新的对象[1,2,3,4,5]。所以,g2array_2依旧同时指向一个地址,所以都更新成了新对象[1,2,3,4,5]

你可能感兴趣的:(疯狂的Python-06(时间的误会))