Obviamente, está preguntando por el número de elementos en la lista. Si un buscador viene aquí buscando el tamaño del objeto en la memoria, esta es la pregunta y las respuestas reales que está buscando: ¿Cómo determino el tamaño de un objeto en Python?
Aaron Hall
Respuestas:
2640
La len()función se puede usar con varios tipos diferentes en Python, tanto los tipos integrados como los tipos de biblioteca. Por ejemplo:
>>> len([1,2,3])3
La documentación oficial 2.x está aquí: la
documentación oficial 3.x está aquí:len() len()
Todo en Python es un objeto, incluidas las listas. Todos los objetos tienen un encabezado de algún tipo en la implementación de C.
Las listas y otros objetos incorporados similares con un "tamaño" en Python, en particular, tienen un atributo llamado ob_size, donde se almacena en caché el número de elementos en el objeto. Por lo tanto, verificar el número de objetos en una lista es muy rápido.
Devuelve la longitud (el número de elementos) de un objeto. El argumento puede ser una secuencia (como una cadena, bytes, tupla, lista o rango) o una colección (como un diccionario, conjunto o conjunto congelado).
lense implementa con __len__, a partir de los documentos del modelo de datos :
object.__len__(self)
Llamado para implementar la función incorporada len(). Debería devolver la longitud del objeto, un entero> = 0. Además, un objeto que no define un método __nonzero__()[en Python 2 o __bool__()Python 3] y cuyo __len__()método devuelve cero se considera falso en un contexto booleano.
Y también podemos ver que __len__es un método de listas:
items.__len__()
devuelve 3.
Tipos incorporados que puede obtener la len(longitud) de
Y, de hecho, vemos que podemos obtener esta información para todos los tipos descritos:
Si bien esto puede no ser útil debido al hecho de que tendría mucho más sentido como una funcionalidad "lista para usar", un truco bastante simple sería construir una clase con una lengthpropiedad:
class slist(list):@propertydef length(self):return len(self)
Puedes usarlo así:
>>> l = slist(range(10))>>> l.length
10>>>print l
[0,1,2,3,4,5,6,7,8,9]
Esencialmente, es exactamente idéntico a un objeto de lista, con el beneficio adicional de tener una lengthpropiedad compatible con OOP .
para que lo sepas, puedes hacer length = property(len)y omitir la función de envoltura de una línea y mantener la documentación / introspección de lentu propiedad.
Tadhg McDonald-Jensen
17
Además lentambién puedes usar operator.length_hint(requiere Python 3.4+). Para una normal, listambos son equivalentes, pero length_hinthacen posible obtener la longitud de un iterador de lista, lo que podría ser útil en ciertas circunstancias:
>>>from operator import length_hint
>>> l =["apple","orange","banana"]>>> len(l)3>>> length_hint(l)3>>> list_iterator = iter(l)>>> len(list_iterator)TypeError: object of type 'list_iterator' has no len()>>> length_hint(list_iterator)3
Pero, length_hintpor definición, es solo una "pista", por lo que la mayoría de las veces lenes mejor.
He visto varias respuestas que sugieren acceder __len__. Esto está bien cuando se trata de clases integradas como list, pero podría generar problemas con las clases personalizadas, porque len(e length_hint) implementan algunas comprobaciones de seguridad. Por ejemplo, ambos no permiten longitudes negativas o longitudes que excedan un cierto valor (el sys.maxsizevalor). ¡Así que siempre es más seguro usar la lenfunción en lugar del __len__método!
En Python, los nombres que comienzan con guiones bajos son métodos semánticamente no públicos y no deben ser utilizados por los usuarios.
Aaron Hall
2
1 __foo__.: esto es solo una convención, una forma para que el sistema Python use nombres que no entren en conflicto con los nombres de usuario. 2 _foo.: esto es solo una convención, una forma para que el programador indique que la variable es privada (lo que sea que eso signifique en Python). 3 __foo.: esto tiene un significado real: el intérprete reemplaza este nombre por _classname__foouna forma de garantizar que el nombre no se superponga con un nombre similar en otra clase. * Ninguna otra forma de guiones bajos tiene significado en el mundo de Python. * No hay diferencia entre clase, variable, global, etc. en estas convenciones.
Shai Alon
44
Estas preguntas y respuestas explican por qué no debe utilizar los métodos especiales directamente como usuario: stackoverflow.com/q/40272161/541136
Aaron Hall
@AaronHall pero para la función len es casi lo mismo. Puede ser más rápido para variables muy grandes. Sin embargo, entiendo su punto y deberíamos usar len (obj) y no obj .__ len __ ().
Shai Alon
7
Y para completar (principalmente educativo), es posible sin usar la len()función. No aprobaría esto como una buena opción. NO PROGRAMAR ASÍ COMO ESTO EN PYTHON , pero sirve para aprender algoritmos.
(Los dos puntos en list[:]están implícitos y, por lo tanto, también son opcionales).
La lección aquí para los nuevos programadores es: no se puede obtener el número de elementos en una lista sin contarlos en algún momento. La pregunta es: ¿cuándo es un buen momento para contarlos? Por ejemplo, el código de alto rendimiento, como la llamada de conexión del sistema para enchufes (escrito en C) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);, no calcula la longitud de los elementos (dando esa responsabilidad al código de llamada). ¿Observe que se pasa la longitud de la dirección para guardar el paso de contar primero la longitud? Otra opción: computacionalmente, podría tener sentido hacer un seguimiento de la cantidad de elementos a medida que los agrega dentro del objeto que pasa. Tenga en cuenta que esto ocupa más espacio en la memoria. Ver la respuesta de Naftuli Kay .
Ejemplo de hacer un seguimiento de la longitud para mejorar el rendimiento mientras ocupa más espacio en la memoria. Tenga en cuenta que nunca uso la función len () porque se realiza un seguimiento de la longitud:
classMyList(object):def __init__(self):
self._data =[]
self.length =0# length tracker that takes up memory but makes length op O(1) time# the implicit iterator in a list classdef __iter__(self):for elem in self._data:yield elem
def add(self, elem):
self._data.append(elem)
self.length +=1def remove(self, elem):
self._data.remove(elem)
self.length -=1
mylist =MyList()
mylist.add(1)
mylist.add(2)
mylist.add(3)print(mylist.length)# 3
mylist.remove(3)print(mylist.length)# 2
¿Por qué for item in list[:]:? ¿Por qué no for item in list:? Además, lo usaría += 1para incrementar.
Granny Aching
@GrannyAching Mencioné explícitamente los dos puntos opcionales (especificador de rango). Dejé el especificador de rango allí con fines educativos; es beneficioso saber que está implícito. También se infiere un tipo de lista [], como sugiere, equivalente a mi código. El operador de incremento también es equivalente a agregar 1 a una variable existente, pero más corto en todos los casos. Así que estoy de acuerdo en que debería usarse si ese es su razonamiento. Este código no debe ponerse en producción en ninguna parte, de todos modos (excepto cuando se aprende programación).
static PyObject*
builtin_len(PyObject*module,PyObject*obj)/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/{Py_ssize_t res;
res =PyObject_Size(obj);if(res <0){assert(PyErr_Occurred());return NULL;}returnPyLong_FromSsize_t(res);}
Py_ssize_tes la longitud máxima que puede tener el objeto. PyObject_Size()es una función que devuelve el tamaño de un objeto. Si no puede determinar el tamaño de un objeto, devuelve -1. En ese caso, este bloque de código se ejecutará:
if(res <0){assert(PyErr_Occurred());return NULL;}
Y como resultado se plantea una excepción. De lo contrario, este bloque de código se ejecutará:
returnPyLong_FromSsize_t(res);
resque es un Centero, se convierte en una pitón longy se devuelve. Todos los enteros de Python se almacenan como longsdesde Python 3.
Respuestas:
La
len()
función se puede usar con varios tipos diferentes en Python, tanto los tipos integrados como los tipos de biblioteca. Por ejemplo:La documentación oficial 2.x está aquí: la documentación oficial 3.x está aquí:
len()
len()
fuente
Para encontrar el tamaño de una lista, use la función integrada
len
:Y ahora:
devuelve 3.
Explicación
Todo en Python es un objeto, incluidas las listas. Todos los objetos tienen un encabezado de algún tipo en la implementación de C.
Las listas y otros objetos incorporados similares con un "tamaño" en Python, en particular, tienen un atributo llamado
ob_size
, donde se almacena en caché el número de elementos en el objeto. Por lo tanto, verificar el número de objetos en una lista es muy rápido.Pero si está comprobando si el tamaño de la lista es cero o no, no use
len
, en su lugar, coloque la lista en un contexto booleano, se tratará como Falso si está vacío, de lo contrario, es cierto .De los documentos
len(s)
len
se implementa con__len__
, a partir de los documentos del modelo de datos :object.__len__(self)
Y también podemos ver que
__len__
es un método de listas:devuelve 3.
Tipos incorporados que puede obtener la
len
(longitud) deY, de hecho, vemos que podemos obtener esta información para todos los tipos descritos:
No lo use
len
para probar una lista vacía o no vacíaPara probar una longitud específica, por supuesto, simplemente pruebe la igualdad:
Pero hay un caso especial para probar una lista de longitud cero o la inversa. En ese caso, no pruebe la igualdad.
Además, no hagas:
En cambio, simplemente haz:
o
Me explico por qué aquí , pero en fin,
if items
oif not items
es tanto más fácil de leer y con más prestaciones.fuente
Si bien esto puede no ser útil debido al hecho de que tendría mucho más sentido como una funcionalidad "lista para usar", un truco bastante simple sería construir una clase con una
length
propiedad:Puedes usarlo así:
Esencialmente, es exactamente idéntico a un objeto de lista, con el beneficio adicional de tener una
length
propiedad compatible con OOP .Como siempre, su kilometraje puede variar.
fuente
length = property(len)
y omitir la función de envoltura de una línea y mantener la documentación / introspección delen
tu propiedad.Además
len
también puedes usaroperator.length_hint
(requiere Python 3.4+). Para una normal,list
ambos son equivalentes, perolength_hint
hacen posible obtener la longitud de un iterador de lista, lo que podría ser útil en ciertas circunstancias:Pero,
length_hint
por definición, es solo una "pista", por lo que la mayoría de las veceslen
es mejor.He visto varias respuestas que sugieren acceder
__len__
. Esto está bien cuando se trata de clases integradas comolist
, pero podría generar problemas con las clases personalizadas, porquelen
(elength_hint
) implementan algunas comprobaciones de seguridad. Por ejemplo, ambos no permiten longitudes negativas o longitudes que excedan un cierto valor (elsys.maxsize
valor). ¡Así que siempre es más seguro usar lalen
función en lugar del__len__
método!fuente
Responde tu pregunta como los ejemplos también dados anteriormente:
fuente
__foo__
.: esto es solo una convención, una forma para que el sistema Python use nombres que no entren en conflicto con los nombres de usuario. 2_foo
.: esto es solo una convención, una forma para que el programador indique que la variable es privada (lo que sea que eso signifique en Python). 3__foo
.: esto tiene un significado real: el intérprete reemplaza este nombre por_classname__foo
una forma de garantizar que el nombre no se superponga con un nombre similar en otra clase. * Ninguna otra forma de guiones bajos tiene significado en el mundo de Python. * No hay diferencia entre clase, variable, global, etc. en estas convenciones.Y para completar (principalmente educativo), es posible sin usar la
len()
función. No aprobaría esto como una buena opción. NO PROGRAMAR ASÍ COMO ESTO EN PYTHON , pero sirve para aprender algoritmos.(Los dos puntos en
list[:]
están implícitos y, por lo tanto, también son opcionales).La lección aquí para los nuevos programadores es: no se puede obtener el número de elementos en una lista sin contarlos en algún momento. La pregunta es: ¿cuándo es un buen momento para contarlos? Por ejemplo, el código de alto rendimiento, como la llamada de conexión del sistema para enchufes (escrito en C)
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
, no calcula la longitud de los elementos (dando esa responsabilidad al código de llamada). ¿Observe que se pasa la longitud de la dirección para guardar el paso de contar primero la longitud? Otra opción: computacionalmente, podría tener sentido hacer un seguimiento de la cantidad de elementos a medida que los agrega dentro del objeto que pasa. Tenga en cuenta que esto ocupa más espacio en la memoria. Ver la respuesta de Naftuli Kay .Ejemplo de hacer un seguimiento de la longitud para mejorar el rendimiento mientras ocupa más espacio en la memoria. Tenga en cuenta que nunca uso la función len () porque se realiza un seguimiento de la longitud:
fuente
for item in list[:]:
? ¿Por qué nofor item in list:
? Además, lo usaría+= 1
para incrementar.En términos de cómo
len()
funciona realmente, esta es su implementación en C :Py_ssize_t
es la longitud máxima que puede tener el objeto.PyObject_Size()
es una función que devuelve el tamaño de un objeto. Si no puede determinar el tamaño de un objeto, devuelve -1. En ese caso, este bloque de código se ejecutará:Y como resultado se plantea una excepción. De lo contrario, este bloque de código se ejecutará:
res
que es unC
entero, se convierte en una pitónlong
y se devuelve. Todos los enteros de Python se almacenan comolongs
desde Python 3.fuente