快速Python前端列表扩展

5
什么是Python中在数组前端扩展的最快方法?假设我有2个数组a和b,我想让a = b+a(b不应更改)成为最快的方法。
我的简单基准测试:
测试1:
a,b = [],[]
for i in range(0,100000):
    a.append(i)
    b.append(i)

def f(a,b):
    for i in range(0,100):
        a=a+b

import cProfile
cProfile.run('f(a,b)')

时间:约12秒

测试2:

a,b = [],[]
for i in range(0,100000):
    a.append(i)
    b.append(i)

def f(a,b):
    for i in range(0,100):
        a[0:0] = b

import cProfile
cProfile.run('f(a,b)')

时间:约1.5秒

测试3:

a,b = [],[]
for i in range(0,100000):
    a.append(i)
    b.append(i)

lenb = len(b)
def f(a,b):
    for i in range(0,100):
        b.extend(a)
        # do something with b
        b = b[:lenb]

import cProfile
cProfile.run('f(a,b)')

时间:约0.4秒

但我认为它应该更快,因为列表连接应该是通过改变一些底层指针来实现的。 以下代码是最快的,但它改变了b而不是a(所以对我们的目的不好): 测试"WRONG":

a,b = [],[]
for i in range(0,100000):
    a.append(i)
    b.append(i)

def f(a,b):
    for i in range(0,100):
        b.extend(a)

import cProfile
cProfile.run('f(a,b)')

时间:约0.13秒

理论上讲,在测试期间应该有一种方法来扩展a标签的前面,但是实践发现这样做是错误的。


5
导入双端队列的模块。 - eumiro
1
注意,你手头的是列表,而不是数组。 - Daniel Roseman
1个回答

10

最快的方法是使用collections.deque,它专为这种用途进行了优化,并且具有称为.appendleft.extendleft的方法,使代码更加易读 - appendleft正如其名(即将元素添加到deque左侧),而extendleft则相当于:

def extendleft(self, other)
    for item in other:
        self.appendleft(c)

因此,a = b+a 的拼写方式为:

a.extendleft(reversed(b))

你想使用 a.extendleft(reversed(b)),因为 extendleft 从头部开始消耗给定的可迭代对象(就像蛇吃老鼠一样)。 - eumiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接