2012-06-21 45 views
5

Dizinin önünü python'da genişletmenin en hızlı yolu nedir? 2 dizim var diyor: a ve b. A = b + a'nın en hızlı yolunu yapmak istiyorum (b değişmemelidir).Hızlı python ön listesi genişletme

Benim küçük benchamarks:

testi 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)') 

süresi: ~ 12 s

testi 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)') 

süresi: ~ 1.5s

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)') 

süresi: ~ 0,4 saniyeden

Ama listeleri birleştirme birkaç yatan işaretçileri değişiklik olarak yapılmalıdır, çünkü daha hızlı olması gerektiğini düşünüyorum. Ve aşağıdaki kod en hızlı biri, ancak b değiştirir, bir (SO BU, BİR AMAÇ İÇİN İYİ DEĞİL) değil: testi "YANLIŞ":

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)') 

süresi: ~ Yani 0.13s

teorik olarak, "WRONG" test zamanının önünü uzatmanın bir yolu olmalıdır.

+5

'im koleksiyonlardan port deque' – eumiro

+1

Not, sahip olduklarınız, diziler değil listeler. –

cevap

10

mutlak en hızlı şekilde tam olarak bu kullanım için optimize edilmiş bir collections.deque kullanmak olacaktır, ve kod güzel yapmak için .appendleft ve .extendleft denilen ve okunabilir olan yöntemler - appendleft o (teneke yazdığını yapar yani o) deque solundaki ekler ve extendleft eşdeğer yapar: o kadar

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

, a = b+a yazıldığından olacaktır:

a.extendleft(reversed(b)) 
+0

Eğer "extendleft" kendi başından yinelenen verimi (tıpkı bir fare yiyen bir yılan gibi) tükettiğinden dolayı "a.extendleft (ters (b))" yi kullanmak istersiniz. – eumiro

+0

@eumiro teşekkürler; Bunu cevabımda düzelttim. – lvc