我试图找出列表的切片分配和常规分配之间的性能差异。代码如下:
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
我的期望是,对于每个列表a
和b
,这将一次删除一个元素,以便print a
和print b
都打印空列表。相反,它们似乎总是打印开始列表,但是缺少了第一个256
元素。你知道吗
它们都打印:
[257, 258, 259 ... N-1]
发生了什么事?你知道吗
我使用的是python2.7.6。你知道吗
问题是您使用的是
is
而不是==
。你知道吗前者检查对象的身份,而不是相等。没有理由相信,两次求值
300+1
会得到相同的int
对象,只是它们都会得到值为int
的int
对象。你知道吗对于256以内的数字,这是“有效”的,因为特定的Python实现*会处理256以内的内部整数。在启动时,它为数
1
创建一个单例对象,为2
创建一个单例对象,依此类推。任何时候一个表达式的计算结果是1
,它都会给出那个对象,而不是一个新的对象。**不用说,您不应该依赖于这种优化。你知道吗
*IIRC,从1.x天到3.5天的每个版本的CPython对于-5到256的所有整数都默认此行为,但是您可以在生成时更改这些限制,或者关闭该功能,不同的实现可能会做一些不同的事情。
**。您可以看到代码的3.4版本,例如,here;它调用的宏
CHECK_SMALL_INT
和实际函数get_small_int
,以及函数使用的静态数组,都在同一个文件中,位于顶部附近。相关问题 更多 >
编程相关推荐