2012-06-21 14 views
5

Qual è il modo più veloce per estendere la parte anteriore di un array in python? Diciamo che ho 2 matrici: a e b. Voglio fare il modo più veloce di a = b + a (b non dovrebbe cambiare).Elenco rapido python anteriore che si estende

mio piccolo benchamarks:

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

tempo: ~ 12 s

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

tempo: ~ 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)') 

tempo: ~ 0.4s

ma penso che dovrebbe essere più veloce, perché le liste concatenazione deve essere fatto come il cambiamento di alcune indicazioni sottostanti. E il seguente codice è il più veloce, ma cambia B, non un (SO non è bene per il nostro scopo): test "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)') 

tempo: ~ 0.13s

Così teoricamente dovrebbe esserci un modo per estendere la parte anteriore del tempo di test "ERRATO".

+5

'da collezioni im port deque' – eumiro

+1

Nota, quello che hai sono liste, non matrici. –

risposta

10

Il modo più veloce in assoluto sarebbe quella di utilizzare un collections.deque che è ottimizzato proprio per questo uso, e ha metodi chiamato .appendleft e .extendleft per rendere il codice bello e leggibile - appendleft fa esattamente quello che dice sulla latta (cioè, accoda alla sinistra del deque), e extendleft fa l'equivalente di:

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

così, sarebbe farro a = b+a:

a.extendleft(reversed(b)) 
+0

Si desidera utilizzare 'a.extendleft (invertito (b))' perché 'extendleft' consuma il dato iterabile dalla sua testa (proprio come un serpente che mangia un topo). – eumiro

+0

@ eumiro grazie; L'ho risolto nella mia risposta. – lvc

Problemi correlati