oyv*_*ind 2 python list variable-assignment
我试图找到切片分配和列表的常规分配之间的性能差异.这是代码:
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
Run Code Online (Sandbox Code Playgroud)
我的期望是,每个列表a和b,这一次删除一个元素,这样print a和print b两个打印空列表.相反,他们似乎总是打印起始列表,但256缺少第一个元素.
他们都打印:
[257, 258, 259 ... N-1]
Run Code Online (Sandbox Code Playgroud)
怎么了?
我正在使用Python 2.7.6.
问题是你用的是is代替==.
前者检查对象身份,而不是平等.没有理由相信评估,比方说,300+1两次会给你相同的int对象,只是他们都会给你int价值的对象301.
出现这种情况,为数字"工作"多达256个,因为您的特定Python实现*恰好实习生整数高达256启动时,它创造了多少单身的对象1,对于一个单独的对象2,依此类推.只要表达式求值为数字1,它就会为您提供该对象,而不是新对象.**
不用说,你不应该依赖于这种优化.
*IIRC,从1.x天到3.5的每个版本的CPython都默认为-5到256之间的所有整数的行为,但你可以在构建时更改这些限制或关闭该功能,并且可能会有不同的实现做点别的事.
**如果你想知道它在CPython中是如何工作的,那么在C API级别,PyLong_FromLong通过在单例值数组中查找从-5到256的数字来实现这一点.你可以看到3.4版本的代码,例如,这里 ; 它调用的宏CHECK_SMALL_INT和实际函数get_small_int,以及函数使用的静态数组都在同一个文件中,靠近顶部.