列表理解赋值/比较256后失败

2024-04-20 14:26:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找出列表的切片分配和常规分配之间的性能差异。代码如下:

import time

N =  1000  
a = list(range(N))
b = list(range(N))

time1 = time.time()
for i in range(N):
    a = [x for x in a if x is not i]
time2 = time.time()
for i in range(N):
    b[:] = [x for x in b if x is not i]
time3 = time.time()

print a
print b    
print time2 - time1
print time3 - time2

我的期望是,对于每个列表ab,这将一次删除一个元素,以便print aprint b都打印空列表。相反,它们似乎总是打印开始列表,但是缺少了第一个256元素。你知道吗

它们都打印:

[257, 258, 259 ... N-1]

发生了什么事?你知道吗

我使用的是python2.7.6。你知道吗


Tags: in元素列表foriftimeisnot
1条回答
网友
1楼 · 发布于 2024-04-20 14:26:46

问题是您使用的是is而不是==。你知道吗

前者检查对象的身份,而不是相等。没有理由相信,两次求值300+1会得到相同的int对象,只是它们都会得到值为intint对象。你知道吗

对于256以内的数字,这是“有效”的,因为特定的Python实现*会处理256以内的内部整数。在启动时,它为数1创建一个单例对象,为2创建一个单例对象,依此类推。任何时候一个表达式的计算结果是1,它都会给出那个对象,而不是一个新的对象。**

不用说,您不应该依赖于这种优化。你知道吗


*IIRC,从1.x天到3.5天的每个版本的CPython对于-5到256的所有整数都默认此行为,但是您可以在生成时更改这些限制,或者关闭该功能,不同的实现可能会做一些不同的事情。

**。您可以看到代码的3.4版本,例如,here;它调用的宏CHECK_SMALL_INT和实际函数get_small_int,以及函数使用的静态数组,都在同一个文件中,位于顶部附近。

相关问题 更多 >