Python: ¿Las listas de Python mantienen un recuento de len () o cuentan para cada llamada?

79

Si sigo llamando a len () en una lista muy larga, ¿estoy perdiendo el tiempo o mantiene un recuento de int en segundo plano?

PKKid
fuente
Esto siempre me molestó. especialmente cuando mi generador de perfiles me dijo que pasé 2.2 segundos de un programa que se ejecutó durante un minuto llamando a esta función.
Nathan

Respuestas:

87

No se preocupe: por supuesto, guarda el recuento y, len()por lo tanto, en las listas es una operación bastante barata. ¡Lo mismo ocurre con las cadenas, los diccionarios y los conjuntos, por cierto!

Ferdinand Beyer
fuente
Creo que mantiene un recuento como el índice del último elemento + 1 o algo, y llama al valor de len () desde esa ubicación de memoria. Estoy en lo cierto?
geekidharsh
13

Escriba su programa de modo que esté optimizado para mayor claridad y fácil de mantener . ¿Su programa es más claro con una llamada a len(foo)? Entonces haz eso.

¿Le preocupa el tiempo que lleva? Utilice el timeitmódulo de la biblioteca estándar para medir el tiempo necesario y ver si es significativo en su código.

Como la mayoría de la gente, es muy probable que se equivoque al adivinar qué partes de su programa son más lentas. Evite la tentación de adivinar y, en cambio, mida para averiguarlo.

Recuerde que la optimización prematura es la raíz de todos los males , en palabras de Donald Knuth. Concéntrese únicamente en la velocidad del código cuya velocidad ha medido para saber si el beneficio valdría la pena el costo de cambiar su funcionamiento.

nariz grande
fuente
1
Soy programador con solo unos meses en mi trabajo y apoyo ambas prácticas. El asunto del temporizador ofrece una defensa de dos líneas contra una gran cantidad de sabiduría convencional ("SELECCIONAR ... ALEATORIO es demasiado caro") que se lanzará en su camino.
Jesvin Jose
5

La pregunta ha sido respondida ( lenes O (1)), pero así es como puede verificarlo usted mismo:

$ python -m timeit -s "l = range(10)" "len(l)"
10000000 loops, best of 3: 0.119 usec per loop
$ python -m timeit -s "l = range(1000000)" "len(l)"
10000000 loops, best of 3: 0.131 usec per loop

Sí, no más lento.

dF.
fuente
3

Una "lista" de Python es en realidad una matriz redimensionable, no una lista vinculada, por lo que almacena el tamaño en algún lugar.

Conocido
fuente
0

Tiene que almacenar la longitud en algún lugar, por lo que no está contando la cantidad de elementos cada vez.

Georg Schölly
fuente
4
Tenga cuidado, esto no es necesariamente cierto en todos los idiomas. Algunos idiomas realmente usan listas vinculadas y pueden o no mantener metadatos sobre el tamaño. Un ejemplo perfecto es Lisp, donde las listas usan estructuras de 2 celdas relativamente primitivas para construirse, sin metadatos. En estos casos, una llamada de larga duración lleva O (n) tiempo.
Ashton K