Lista de Python () frente a la velocidad de construcción de comprensión de lista

Esto es interesante; list() para forzar a un iterador a obtener la lista real es mucho más rápido que [x for x in someList] (comprensión).

¿Es esto real o mi prueba es demasiado simple? A continuación se muestra el código:

 import time timer = time.clock() for i in xrange(90): #localList = [x for x in xrange(1000000)] #Very slow, took me 6.8s localList = list(xrange(1000000)) #Very fast, took me 0.9s print localList[999999] #make sure list is really evaluated. print "Total time: ", time.clock() - timer 

La lista de comprensión ejecuta el bucle en el bytecode de Python, al igual que un bucle normal for .

La llamada a list() itera completamente en código C, que es mucho más rápido.

El bytecode para la lista de comprensión se ve así:

 >>> import dis >>> dis.dis(compile("[x for x in xrange(1000000)]", '', 'exec')) 1 0 BUILD_LIST 0 3 LOAD_NAME 0 (xrange) 6 LOAD_CONST 0 (1000000) 9 CALL_FUNCTION 1 12 GET_ITER >> 13 FOR_ITER 12 (to 28) 16 STORE_NAME 1 (x) 19 LOAD_NAME 1 (x) 22 LIST_APPEND 2 25 JUMP_ABSOLUTE 13 >> 28 POP_TOP 29 LOAD_CONST 1 (None) 32 RETURN_VALUE 

Los >> punteros aproximadamente le dan los límites del bucle que se está ejecutando, por lo que tiene 1 millón de STORE_NAME , LOAD_NAME y LIST_APPEND para ejecutar en el bucle de evaluación de bytecode de Python.

list() por otro lado, simplemente toma los valores del xrange() iterable directamente usando la API de C para la iteración del objeto, y puede usar la longitud del objeto xrange() para preasignar el objeto de la lista en lugar de boostla. dinamicamente.