¿Cuál es la forma más eficiente de iterar a través de una lista en python?

Digamos que tengo una lista de artículos:

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

Necesito realizar algunas funciones para cada uno de estos elementos. En un caso determinado, necesito devolver el índice de un artículo.

¿Cuál es la forma mejor y más eficiente?

 for item in list: .... 

o

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

 for item in list: 

es obviamente el que tiene menos llamadas a funciones.

Si desea obtener el índice de elementos a medida que avanza, utilice enumerar así

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

La comprobación con dis nos da el siguiente código de bytes para 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 

El bytecode para loop_2 se ve así:

 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 segunda versión es obviamente mejor.

Otra solución posible sería utilizar numpy que sería muy eficiente, para listas grandes quizás incluso más eficiente que una comprensión de listas o un bucle 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.]) 

Esta es una operación bastante simple, pero puede ser más complejo si usa una matriz simplemente como un argumento en una fórmula. Para matrices grandes, esto puede ser mucho más rápido que una comprensión de lista y hace que el código sea más limpio y fácil de leer (no es necesario crear una función para mapear en una comprensión de lista). También puede usar la indexación y el corte para adaptar lo que quiere hacer:

Si desea tener acceso a las posiciones de índice reales, utilice ndenumerate

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

La salida de este bucle para es:

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

NOTA: el índice devuelto como una tupla por número para manejar dimensiones adicionales. Aquí solo tenemos una dimensión, por lo que tendremos que desempaquetar la tupla para obtener el índice del elemento.

Obviamente for i in range(len(list)): será más lento, es equivalente a esto:

 list2 = range(len(list)) for i in list2: ... 

Si eso fuera más rápido, entonces esto sería aún más rápido, ¿verdad?

 list2 = range(len(list)) list3 = range(len(list2)) list4 = range(len(list3)) for i in list4: ...