2012-06-21 7 views
5

Pythonで配列の前面を拡張する最も速い方法は何ですか?私は2つの配列を持っていると言う: aとb。私はa = b + aの最速の方法を作りたいです(bは変えてはいけません)。高速なPythonフロントリストの拡張

私の小さなbenchamarks:

テスト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秒

test3:

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を変更し、(SO ITは、我々の目的のために良いではありません)ではない: テスト "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.13s

理論的には、テストの時間を「間違って」延長する方法があるはずです。

+5

を 'イムコレクションからport deque' – eumiro

+1

あなたが持っているものはリストであり、配列ではありません。 –

答えて

10

絶対最速の方法は、まさにこの使用のために最適化されcollections.dequeを使用することで、そしてコードは素晴らしく、読みやすくするため.appendleft.extendleftと呼ばれる方法があるでしょう - appendleftは、それは錫で言うまさにません(すなわち、それは)両端キューの左側に付加し、そしてextendleftは相当行いますので

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

を、a = b+aが綴られます:

a.extendleft(reversed(b)) 
+0

'a.extendleft(reverseed(b))'を使用したいのは、 'extendleft'が与えられたiterableをその頭から消費する(まるで蛇のようにマウスを食べるように)ためです。 @ umiroありがとうございました; – eumiro

+0

;私は私の答えでそれを修正しました。 – lvc