recorrer por listas lista elementos ejemplo diccionarios diccionario dentro convertir comprensión agregar python

elementos - ¿Por qué la función len no es heredada por diccionarios y listas en Python?



listas por comprensión python (7)

ejemplo:

a_list = [1, 2, 3] a_list.len() # doesn''t work len(a_list) # works

Python está (muy) orientado a objetos, no entiendo por qué la función ''len'' no es heredada por el objeto. Además, sigo intentando la solución equivocada, ya que parece ser la más lógica para mí


Bueno, en realidad hay un método de longitud, simplemente está oculto:

>>> a_list = [1, 2, 3] >>> a_list.__len__() 3

La función incorporada len () parece ser simplemente un contenedor para una llamada al método ocul () len del objeto.

Sin embargo, no estoy seguro de por qué tomaron la decisión de implementar las cosas de esta manera.


De esta manera encaja mejor con el resto del lenguaje. La convención en python es que se agregan __foo__ métodos especiales a los objetos para que tengan ciertas capacidades (en lugar de, por ejemplo, derivar de una clase base específica). Por ejemplo, un objeto es

  • invocable si tiene un método __call__
  • iterable si tiene un método __iter__ ,
  • admite el acceso con [] si tiene __getitem__ y __setitem__ .
  • ...

Uno de estos métodos especiales es __len__ que hace que tenga una longitud accesible con len() .


La explicación de Guido está aquí :

En primer lugar, elegí len (x) sobre x.len () para razones de HCI (def __len __ () llegó mucho más tarde). En realidad, hay dos razones entrelazadas, ambas HCI:

(a) Para algunas operaciones, la notación de prefijo simplemente lee mejor que postfix - las operaciones de prefijo (¡e infijo!) tienen una larga tradición en matemáticas a las que les gustan las notaciones donde los elementos visuales ayudan al matemático a pensar en un problema. Compare la facilidad con la que reescribimos una fórmula como x * (a + b) en x a + x b a la torpeza de hacer lo mismo usando una notación OO cruda.

(b) Cuando leo un código que dice len (x) sé que está pidiendo la longitud de algo. Esto me dice dos cosas: el resultado es un número entero, y el argumento es algún tipo de contenedor. Por el contrario, cuando leo x.len (), tengo que saber que x es un tipo de contenedor que implementa una interfaz o hereda de una clase que tiene un len () estándar. Sea testigo de la confusión que ocasionalmente tenemos cuando una clase que no implementa una asignación tiene un método get () o keys (), o algo que no es un archivo tiene un método write ().

Al decir lo mismo de otra manera, veo ''len'' como una operación incorporada. Odiaría perder eso. / ... /


Simplemente no lo es.

Sin embargo, puedes:

>>> [1,2,3].__len__() 3

Agregar un __len__() a una clase es lo que hace que la magia len() funcione.


Tal vez estás buscando __len__ . Si ese método existe, len (a) lo llama:

>>> class Spam: ... def __len__(self): return 3 ... >>> s = Spam() >>> len(s) 3



La respuesta corta: 1) compatibilidad con versiones anteriores y 2) no hay suficiente diferencia para que realmente importe. Para una explicación más detallada, sigue leyendo.

El enfoque idiomático de Python para tales operaciones es métodos especiales que no están destinados a ser llamados directamente. Por ejemplo, para hacer que x + y funcione para su propia clase, escriba un método __add__ . Para asegurarse de que int(spam) convierta correctamente su clase personalizada, escriba un método __int__ . Para asegurarse de que len(foo) haga algo sensato, escriba un método __len__ .

Así es como siempre han sido las cosas con Python, y creo que tiene mucho sentido para algunas cosas. En particular, esto parece una forma sensata de implementar la sobrecarga del operador. En cuanto al resto, los diferentes idiomas no están de acuerdo; en Ruby convertirías algo a un entero llamando directamente a spam.to_i lugar de decir int(spam) .

Tiene razón en que Python es un lenguaje extremadamente orientado a objetos y que tener que llamar a una función externa en un objeto para obtener su longitud parece extraño. Por otro lado, len(silly_walks) no es más oneroso que silly_walks.len() , y Guido ha dicho que realmente lo prefiere ( http://mail.python.org/pipermail/python-3000/2006- Noviembre / 004643.html ).