在python中,n项对列表和[0]*n的不同追加?

在python中,n项对列表和[0]*n的不同追加?,python,Python,我有两个相同的代码 Code1 >>> a=[0]*60000000 Code2 >>> a=[] >>> for i in range(0,60000000): a.append(0) 在我的电脑中,Code1需要的时间是1s,而Code2需要的时间是480s 为什么?有什么不同?在Python 2.7中,range本身创建一个列表,而不是迭代器。因此,您在Code2中的工作要加倍。这意味着,您首先创建一个包含60000

我有两个相同的代码
Code1

>>> a=[0]*60000000
Code2

>>> a=[]
>>> for i in range(0,60000000):
        a.append(0)
在我的电脑中,
Code1
需要的时间是1s,而
Code2
需要的时间是480s

为什么?有什么不同?

在Python 2.7中,range
本身创建一个列表,而不是迭代器。因此,您在
Code2
中的工作要加倍。这意味着,您首先创建一个包含6000000项的列表,然后对其进行迭代<代码>代码1不需要中间步骤

此[range]是一个多功能函数,用于创建包含算术运算的列表 进展

资源:

将其与Python3.x进行比较:

range不是一个函数,而是一个不可变的序列 类型,如范围和序列类型-列表、元组、范围中所述

资料来源:


尝试使用
xrange
而不是
range
,然后再次进行测试。

忽略使用
range
而不是
xrange
的事实,有两件事正在发生:

1) 这些函数做的事情并不相同,尽管它们得到的是相同的输出。你的
code1
意味着“6000万份
[0]
连在一起”。显然,这不是
Code2
正在做的事情——它必须调用列表的
append
方法6000万次

2) python中的显式循环速度很慢。在
Code1
的某个地方有一个循环,但它是以“C速度”出现的,而不是python速度

def f():
    a = [0]*6000000

def g():
    a = []
    for i in xrange(6000000):
        a.append(0)

%timeit f()
10 loops, best of 3: 31 ms per loop

%timeit g()
1 loops, best of 3: 358 ms per loop
在这样的紧密循环中,大部分开销都在循环本身,而不是其中包含的操作。因此,优化紧循环的一种流行方法是将它们放入一个理解中:

def h():
    [0 for _ in xrange(6000000)]

%timeit h()
10 loops, best of 3: 151 ms per loop
请注意,这两个函数的作用也不相同,这就是为什么
f
h
之间存在差异的原因(在下面的内容中,我假设您使用的是Python 3;在Python 2中,情况类似,但我们必须讨论由于
范围
而导致的内存分配成本)

您的第二个程序在Python字节码中运行。让我们使用模块将其拆解:

循环从字节22到41运行,每次循环,Python都必须解码和执行七字节代码指令,并调用一个函数(函数是
a.append
)。这是4.2亿字节代码指令和6000万函数调用

而您的第一个程序在本机代码中运行:

您可以看到,不仅没有循环,也没有函数调用。所有工作都发生在
二进制乘法指令的“引擎盖下”,该指令发送给,并且由于列表
[0]
仅包含一个元素,因此结果在第529–536行的紧密循环中构造:

if(Py_大小(a)==1){
elem=a->ob_项[0];
对于(i=0;i
code1:纯内存初始化;其中,代码2包含2个开销列表-礼貌范围(),不要忘记for loopOK谢谢。但为什么是时候编写代码2了!=2*1码?!创建列表并使用for比在Code1中所做的工作要昂贵得多,尤其是当您考虑到与操作系统内存处理相关的问题时。
>>> import dis
>>> dis.dis('a=[]\nfor i in range(0,60000000):\n a.append(0)')
  1           0 BUILD_LIST               0 
              3 STORE_NAME               0 (a) 

  2           6 SETUP_LOOP              36 (to 45) 
              9 LOAD_NAME                1 (range) 
             12 LOAD_CONST               0 (0) 
             15 LOAD_CONST               1 (60000000) 
             18 CALL_FUNCTION            2 (2 positional, 0 keyword pair) 
             21 GET_ITER             
        >>   22 FOR_ITER                19 (to 44) 
             25 STORE_NAME               2 (i) 

  3          28 LOAD_NAME                0 (a) 
             31 LOAD_ATTR                3 (append) 
             34 LOAD_CONST               0 (0) 
             37 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
             40 POP_TOP              
             41 JUMP_ABSOLUTE           22 
        >>   44 POP_BLOCK            
        >>   45 LOAD_CONST               2 (None) 
             48 RETURN_VALUE         
>>> dis.dis('a = [0] * 60000000')
  1           0 LOAD_CONST               0 (0) 
              3 BUILD_LIST               1 
              6 LOAD_CONST               1 (60000000) 
              9 BINARY_MULTIPLY      
             10 STORE_NAME               0 (a) 
             13 LOAD_CONST               2 (None) 
             16 RETURN_VALUE