¿Es arr .__ len __ () la forma preferida de obtener la longitud de una matriz en Python?

728

En Python , ¿es la siguiente la única forma de obtener la cantidad de elementos?

arr.__len__()

Si es así, ¿por qué la sintaxis extraña?

Joan Venge
fuente

Respuestas:

1229
my_list = [1,2,3,4,5]
len(my_list)
# 5

Lo mismo funciona para las tuplas:

my_tuple = (1,2,3,4,5)
len(my_tuple)
# 5

Y cadenas, que en realidad son solo matrices de caracteres:

my_string = 'hello world'
len(my_string)
# 11

Se hizo intencionalmente de esta manera para que las listas, las tuplas y otros tipos de contenedores o iterables no necesitaran implementar explícitamente un .length()método público , sino que simplemente puede verificar len()cualquier cosa que implemente el __len__()método 'mágico' .

Claro, esto puede parecer redundante, pero las implementaciones de verificación de longitud pueden variar considerablemente, incluso dentro del mismo idioma. No es raro ver que un tipo de colección use un .length()método mientras que otro tipo usa una .lengthpropiedad, mientras que otro usa .count(). Tener una palabra clave a nivel de idioma unifica el punto de entrada para todos estos tipos. Por lo tanto, incluso los objetos que no consideres como listas de elementos aún podrían verificarse por longitud. Esto incluye cadenas, colas, árboles, etc.

La naturaleza funcional de len()también se presta bien a los estilos funcionales de programación.

lengths = map(len, list_of_containers)
Soviut
fuente
8
len () es un comando de idioma, __len __ () es un método en tipos de contenedor.
Soviut
33
len () es una función global integrada; __len __ () es un método que el objeto puede implementar. len (foo) generalmente termina llamando a foo .__ len __ ().
Tim Lesher
13
Usted menciona que al suministrar len () cada contenedor no tiene que implementar un método .length (), pero ¿cómo es esto diferente, si cada tipo todavía implementa un método __len __ () que de todos modos llama len ()? ¿Len () maneja los diferentes tipos de contenedores de manera diferente?
Simon B. Jensen
10
@Simon: el bit sobre "no todos necesitan implementar .length ()" es confuso. Los tipos de contenedores aún necesitan implementar un método para devolver su longitud; El punto es que es un protocolo estandarizado, no un método ad-hoc que debe buscar para cada tipo. Los guiones bajos dobles significan esto.
Carl Meyer
16
Estoy de acuerdo con Carl Meyer: decir que no "necesita implementar explícitamente" un método .length () público es engañoso y, en su esencia, incorrecto. Cualquier cosa tendrá que implementar len , y siempre puede simplemente implementar su propio método de longitud llamado lo que quieran, evitando la función len. Así que realmente veo esto como una rareza arbitraria que se ajusta a cómo Guido ve el mundo. Probablemente no tiene nada que ver con ningún razonamiento universal.
BT
52

La forma en que tomas una longitud de cualquier cosa para lo que tiene sentido (una lista, diccionario, tupla, cadena, ...) es recurrir lena ella.

l = [1,2,3,4]
s = 'abcde'
len(l) #returns 4
len(s) #returns 5

La razón de la sintaxis "extraña" es que internamente Python se traduce len(object)en object.__len__(). Esto se aplica a cualquier objeto. Entonces, si está definiendo alguna clase y tiene sentido que tenga una longitud, solo defina un __len__()método y luego se puede invocar lenesas instancias.

rz.
fuente
23

Python utiliza la tipificación de pato : que no se preocupa por lo que un objeto es , el tiempo que tiene la interfaz apropiado para la situación en cuestión. Cuando llama a la función incorporada len () en un objeto, en realidad está llamando a su método interno __len__. Un objeto personalizado puede implementar esta interfaz y len () devolverá la respuesta, incluso si el objeto no es conceptualmente una secuencia.

Para obtener una lista completa de interfaces, eche un vistazo aquí: http://docs.python.org/reference/datamodel.html#basic-customization

UncleZeiv
fuente
23

La forma preferida de obtener la longitud de cualquier objeto de Python es pasarlo como argumento a la lenfunción. Internamente, python intentará llamar al __len__método especial del objeto que se pasó.

David Locke
fuente
22

Solo usa len(arr):

>>> import array
>>> arr = array.array('i')
>>> arr.append('2')
>>> arr.__len__()
1
>>> len(arr)
1
Tim Lesher
fuente
10

puede usar len(arr) como se sugiere en respuestas anteriores para obtener la longitud de la matriz. En caso de que desee las dimensiones de una matriz 2D, puede usar arr.shaperetornos alto y ancho

Ahmed Abobakr
fuente
7

len(list_name)La función toma la lista como parámetro y llama a la __len__()función de la lista .

Harun ERGUL
fuente
1

Python sugiere que los usuarios lo usen en len()lugar de __len__()por consistencia, tal como lo dijeron otros chicos. Sin embargo, hay otros beneficios:

Para algunos tipos incorporados como list, str, bytearrayy así sucesivamente, la puesta en práctica de Cython len()toma un atajo. Devuelve directamente el ob_sizeen una estructura C, que es más rápido que llamar__len__() .

Si está interesado en tales detalles, puede leer el libro llamado "Fluent Python" de Luciano Ramalho. Hay muchos detalles interesantes en él y pueden ayudarlo a comprender Python más profundamente.

JOHNKYON
fuente