2012-06-07 14 views
11

Dire che ho un elenco di elementi:Qual è il modo più efficace per scorrere un elenco in python?

x = [1, 2, 3, 4, 5] 

ho bisogno di eseguire alcune funzioni per ciascuno di questi elementi. In un certo caso, ho bisogno di restituire l'indice di un articolo.

Qual è il modo migliore e più efficiente?

for item in list: 
    .... 

o

for i in range(len(list)): 
    .... 
+3

cerca nel forum prima di postare. A questo è stato risposto un milione di volte il possibile duplicazione di [Iterate un elenco con indici in python] (http: // stackoverflow, – sulabh

+0

).it/questions/126524/iterate-a-list-con-indexes-in-python) – jamylak

+0

@sulabh: Non riesco a trovare il duplicato esatto di questa domanda. Si prega di collegare lo stesso. La domanda che sto ponendo è un confronto tra due diversi modi di iterare una lista, e un suggerimento è meglio. – mankand007

risposta

10
for item in list: 

sua ovviamente quello con meno chiamate di funzione.

Se si desidera ottenere l'indice di elementi, come si va utilizzare enumerate come questo

for pos, item in enumerate(collection): 
8
def loop_1(data): 
    for i in range(len(data)): 
     print(data[i]) 


def looper_2(data): 
    for val in data: 
     print(val) 

Verifica con dis ci dà la seguente bytecode per loop_1:

12  0 SETUP_LOOP    40 (to 43) 
      3 LOAD_GLOBAL    0 (range) 
      6 LOAD_GLOBAL    1 (len) 
      9 LOAD_FAST    0 (data) 
     12 CALL_FUNCTION   1 
     15 CALL_FUNCTION   1 
     18 GET_ITER    
    >> 19 FOR_ITER    20 (to 42) 
     22 STORE_FAST    1 (i) 

13  25 LOAD_GLOBAL    2 (print) 
     28 LOAD_FAST    0 (data) 
     31 LOAD_FAST    1 (i) 
     34 BINARY_SUBSCR  
     35 CALL_FUNCTION   1 
     38 POP_TOP    
     39 JUMP_ABSOLUTE   19 
    >> 42 POP_BLOCK   
    >> 43 LOAD_CONST    0 (None) 
     46 RETURN_VALUE   

Il bytecode per loop_2 assomiglia a questo:

17  0 SETUP_LOOP    24 (to 27) 
      3 LOAD_FAST    0 (data) 
      6 GET_ITER    
    >> 7 FOR_ITER    16 (to 26) 
     10 STORE_FAST    1 (val) 

18  13 LOAD_GLOBAL    0 (print) 
     16 LOAD_FAST    1 (val) 
     19 CALL_FUNCTION   1 
     22 POP_TOP    
     23 JUMP_ABSOLUTE   7 
    >> 26 POP_BLOCK   
    >> 27 LOAD_CONST    0 (None) 
     30 RETURN_VALUE 

La seconda versione è ovviamente migliore.

2

Ovviamente for i in range(len(list)): sarà più lento - è equivalente a questo:

list2 = range(len(list)) 

for i in list2: 
    ... 

Se fosse più veloce, allora questo sarebbe ancora più veloce, giusto?

list2 = range(len(list)) 
list3 = range(len(list2)) 
list4 = range(len(list3)) 

for i in list4: 
    ... 
4

Un'altra possibile soluzione potrebbe essere quella di utilizzare numpy che sarebbe molto efficiente, per grandi liste forse anche più efficiente di una lista di comprensione o di un ciclo for.

import numpy as np 

a = np.arange(5.0) # a --> array([0., 1., 2., 3., 4.]) 

# numpy operates on arrays element by element 
# 
b =3.*a    # b --> array([0., 3., 6., 9., 12.]) 

Questo è un piuttosto semplice operazione, ma si può ottenere più complessa usando una matrice semplicemente come un argomento in una formula. Per i grandi array questo può essere molto più veloce di una lista di comprensione e rende il codice più pulito e più facile da leggere (non è necessario creare una funzione per mappare in una lista di comprensione). È inoltre possibile utilizzare l'indicizzazione e affettamento di adattare ciò che si vuole fare:

Se si desidera avere accesso alle posizioni di indice effettivi utilizzare ndenumerate

# b is as above 
for i, x in np.ndenumerate(b): 
    print i, x 

L'uscita di questo ciclo for è:

(0,) 0.0 
(1,) 3.0 
(2,) 6.0 
(3,) 9.0 
(4,) 12.0 

NOTA: l'indice restituito come una tupla numpy per gestire ulteriori dimensioni. Qui abbiamo solo una singola dimensione in modo da dover decomprimere la tupla per ottenere l'indice dell'elemento.

+1

Puoi aggiungere qualche dettaglio a riguardo? –

Problemi correlati