你不知道的Python(2)

今天我们来看看Python的另一个隐藏特性。

首先,我们先来看看如下一段代码:

在上面一段代码中,我们先声明一个list对象,名叫array,然后用一个生成器表达式赋值给g,最后将array重新赋值,那么如果我们把g的内容打印出来会是什么样的呢?

在打印g之前我们可以分析一下这个生成器表达式是要做什么:首先x for x in array是将array中的元素全都取出来,然后if array.count(x)是判断取出来的x的数量是否大于0,如果大于0,则此x满足条件可以添加到g中。那么照此分析来看,打印出来的g中应该包含1、3、5三个元素。

可是果真如此吗?看一下打印出来的g的结果:

我们惊奇的发现,打印出来的g的结果中只含有3,而不含有我们之前推测的还应该包含的元素1和元素3.

这是为什么呢?原来啊,这是因为:在生成器表达式中, in 子句在声明时执行, 而条件子句则是在运行时执行

这就导致在第一条语句中,array的内容实际为[1,3,5],在第二条语句中,x for x in array在此生成器表达式声明时就会运行,所以x for x in array 实际得到的结果为[1,3,5],但是此时array.count(x)>0还不会运行。然后在第三条语句中array的内容被更新为[2,3,4]。当我们在打印g的时候,if array.count(x)>0才会运行,但是此时array的内容已经更新为[2,3,4],而x for x in array 的内容为[1,3,5],所以综合二者看来,满足count(x)>0的元素就只有3。因此最终打印g的结果为[3]。

接下来我们看一下另一个有趣的现象:

根据上面代码,我们可以显然知道g_1的内容应该为[1,2,3],这是因为array_1在被重新赋值的时候,实际上是被绑定到一个新对象[1,2,3,4],而因为生成器表达式中的in子句是在声明时执行,所以其指向的对象实际还是原来的旧对象[1,2,3]。

我们再看一段代码:

在此段代码中我们却发现和上一段代码得到的结果不相同,很显然,问题就出现在第三条语句的切片赋值上。原来啊,切片赋值的时候会将旧对象一起更新,因此生成器表达式g_2和array_2均是指向同一对象,所以打印出的结果为[1,2,3,4]。

好了,这就是在这里要跟大家分享的关于python的一个小特性。

大家可以去多多支持原作者,原链接如下:https://github.com/leisurelicht/wtfpython-cn#structure-of-the-examples%E7%A4%BA%E4%BE%8B%E7%BB%93%E6%9E%84

猜你喜欢

转载自blog.csdn.net/hello15523938742/article/details/85545944