una - ¿Por qué Python trata tuplas, listas, conjuntos y diccionarios como cosas fundamentalmente diferentes?
obtener valores de una tupla python (8)
Una de las razones por las que amo Python es el poder expresivo / esfuerzo de programación reducido proporcionado por tuplas, listas, conjuntos y diccionarios. Una vez que entiendes la lista de comprensión y algunos de los patrones básicos que usan IN y FOR, ¡la vida se pone mucho mejor! Rocas de pitón.
Sin embargo, me pregunto por qué estas construcciones se tratan de manera tan diferente como lo son, y cómo esto está cambiando (volviéndose extraño) con el tiempo. De vuelta en Python 2.x, podría haber argumentado que eran solo variaciones de un tipo de colección básica, y que era un poco irritante que algunos casos de uso no exóticos requieran que conviertas un diccionario a una lista y luego vuelvas. . (¿No es un diccionario solo una lista de tuplas con una restricción de unicidad particular? ¿No es una lista solo un conjunto con un tipo diferente de restricción de unicidad?).
Ahora en el mundo 3.x, se ha vuelto más complicado. Ahora hay nombres de tuplas, que comienzan a parecerse más a un diccionario de casos especiales. Ahora hay diccionarios ordenados, empezando a sentirse más como una lista. Y acabo de ver una receta para sets ordenados. Puedo imaginar que esto sigue y sigue ... ¿qué pasa con las listas únicas, etc.
El zen de Python dice: "Debería haber una, y preferiblemente solo una, obvia forma de hacerlo". Me parece que esta profusión de tipos de colecciones especializadas está en conflicto con este precepto de Python.
¿Qué piensan los hardcore pitonistas?
El zen de Python dice: "Debería haber una, y preferiblemente solo una, obvia forma de hacerlo". Me parece que esta profusión de tipos de colecciones especializadas está en conflicto con este precepto de Python.
No de forma remota. Hay varias cosas diferentes que se están haciendo aquí. Elegimos la herramienta adecuada para el trabajo. Todos estos contenedores están modelados a partir de décadas de probados, probados y verdaderos conceptos de CS.
Los diccionarios no son como las tuplas: están optimizados para búsquedas de valor clave. La tupla también es inmutable, lo que la distingue de una lista (usted podría pensar que es como una lista frozenlist
). Si te encuentras convirtiendo diccionarios a listas y viceversa, es casi seguro que estás haciendo algo mal; Un ejemplo ayudaría.
Las tuplas nombradas existen por conveniencia y están destinadas a reemplazar clases simples en lugar de diccionarios, en realidad. Los diccionarios ordenados son solo un poco de envoltura para recordar el orden en que se agregaron las cosas al diccionario. Y tampoco hay novedades en 3.x (aunque puede haber un mejor soporte de idiomas para ellos; no he visto).
tl; dr (pateando)
Tienes razón al ver algunas similitudes en todas estas estructuras de datos. Recuerda que python usa tipografía de pato (si se parece a un pato y a los curanderos como a un pato, entonces es un pato). Si puede usar dos objetos en la misma situación, entonces, para sus propósitos y propósitos actuales, podrían ser del mismo tipo de datos. Pero siempre hay que tener en cuenta que si intenta usarlos en otras situaciones, es posible que ya no se comporten de la misma manera.
Con esto en mente, deberíamos echar un vistazo a lo que realmente es diferente y lo mismo acerca de los cuatro tipos de datos que mencionó, para tener una idea general de las situaciones en las que son intercambiables.
Mutabilidad (¿puedes cambiarlo?)
Puede realizar cambios en los diccionarios, listas y conjuntos. Las tuplas no se pueden "cambiar" sin hacer una copia.
Mutable:
dict
,list
,set
Inmutable:
tuple
La string
Python también es un tipo inmutable. ¿Por qué queremos algunos objetos inmutables? Parafrasearía de esta respuesta:
Los objetos inmutables se pueden optimizar mucho.
En Python, solo los inmutables son hashable (y solo los objetos hashable pueden ser miembros de conjuntos o claves en los diccionarios).
Comparando a través de esta propiedad, las listas y las tuplas parecen ser los dos tipos de datos "más cercanos". En un nivel alto, una tupla es una versión inmutable de "congelación de fotograma" de una lista. Esto hace que las listas sean útiles para los conjuntos de datos que cambiarán con el tiempo (ya que no tiene que copiar una lista para modificarla), pero las tuplas son útiles para cosas como las claves de diccionario (que deben ser tipos inmutables).
Pedidos (y una nota sobre los tipos de datos abstractos)
Un diccionario, como un conjunto, no tiene un orden conceptual inherente. Esto está en contraste con las listas y tuplas, que tienen un orden. El orden de los elementos en un dict o un conjunto se abstrae del programador, lo que significa que si el elemento A aparece antes que B en a for k in mydata
bucle de datos, no debe (y generalmente no puede) confiar en que A sea antes B una vez que comience a hacer cambios a mydata
.
Conservación de pedidos:
list
,tuple
Sin orden de conservación:
dict
,set
Técnicamente, si recorres mydata
dos veces seguidas, estará en el mismo orden, pero esto es más una característica conveniente de la mecánica de python, y no es realmente una parte del tipo de datos abstractos set
(la definición matemática de los datos). tipo). Sin embargo, las listas y las tuplas garantizan el orden, especialmente las tuplas que son inmutables.
Lo que ves cuando iteras (si camina como un pato ...)
Un "elemento" por "elemento":
set
,list
,tuple
Dos "elementos" por "elemento":
dict
Supongo que aquí podría ver una tupla con nombre, que tiene tanto un nombre como un valor para cada elemento, como un análogo inmutable de un diccionario. Pero esta es una comparación tenue: tenga en cuenta que la tipificación de pato causará problemas si está tratando de usar un método solo de diccionario en una tupla nombrada, o viceversa.
Respuestas directas a tus preguntas.
¿No es un diccionario solo una lista de tuplas con una restricción de singularidad particular?
No, hay varias diferencias. Los diccionarios no tienen un orden inherente, que es diferente de una lista, que sí lo tiene.
Además, un diccionario tiene una clave y un valor para cada "elemento". Una tupla, por otro lado, puede tener un número arbitrario de elementos, pero cada uno con solo un valor.
Debido a la mecánica de un diccionario, donde las claves actúan como un conjunto, puede buscar valores en tiempo constante si tiene la clave. En una lista de tuplas (pares aquí), deberá recorrer la lista hasta que encuentre la clave, lo que significa que la búsqueda sería lineal en el número de elementos de su lista.
Sin embargo, lo más importante es que los elementos del diccionario se pueden cambiar, mientras que las tuplas no se pueden cambiar.
¿No es una lista solo un conjunto con un tipo diferente de restricción de unicidad?
Una vez más, me gustaría hacer hincapié en que los conjuntos no tienen un orden inherente, mientras que las listas sí lo hacen. Esto hace que las listas sean mucho más útiles para representar cosas como pilas y colas, donde desea poder recordar el orden en el que agregó los elementos. Los conjuntos no ofrecen tal garantía. Sin embargo, ofrecen la ventaja de poder realizar búsquedas de membresía en tiempo constante, mientras que nuevamente las listas toman tiempo lineal.
Ahora hay nombres de tuplas, que comienzan a parecerse más a un diccionario de casos especiales. Ahora hay diccionarios ordenados, empezando a sentirse más como una lista. Y acabo de ver una receta para sets ordenados. Puedo imaginar que esto sigue y sigue ... ¿qué pasa con las listas únicas, etc.
Hasta cierto punto estoy de acuerdo contigo. Sin embargo, las bibliotecas de estructuras de datos pueden ser útiles para admitir casos de uso comunes para estructuras de datos ya bien establecidas. Esto evita que el programador pierda el tiempo intentando crear extensiones personalizadas para las estructuras estándar. Siempre que no se salga de control y podamos ver la utilidad única de cada solución, es bueno tener una rueda en el estante para que no sea necesario reinventarla.
Un gran ejemplo es la clase Counter (). Este diccionario especializado me ha sido útil más veces de las que puedo contar (¡badoom-tshhhhh!) Y me ha ahorrado el esfuerzo de codificar una solución personalizada. Prefiero tener una solución que la comunidad me esté ayudando a desarrollar y mantener con las mejores prácticas de Python que a algo que se encuentra en mi carpeta de estructuras de datos personalizadas y que solo se use una o dos veces al año.
El mundo de las estructuras de datos (lenguaje agnóstico) generalmente puede reducirse a unas pocas estructuras básicas pequeñas: listas, árboles, tablas hash y gráficos, etc., y sus variantes y combinaciones. Cada uno tiene su propio propósito específico en términos de uso e implementación.
No creo que pueda hacer cosas como reducir un diccionario a una lista de tuplas con una restricción de singularidad particular sin especificar realmente un diccionario. Un diccionario tiene un propósito específico: búsquedas de clave / valor, y la implementación de la estructura de datos generalmente se adapta a esas necesidades. Los conjuntos son como diccionarios de muchas maneras, pero ciertas operaciones en conjuntos no tienen sentido en un diccionario (unión, disyunción, etc.).
No veo esto violando el ''Zen de Python'' de hacer las cosas de una manera. Si bien puede usar un diccionario ordenado para hacer lo que hace un diccionario sin usar la parte ordenada, está violando más la maquinilla de afeitar de Occam y es probable que cause una penalización de rendimiento. Veo esto como algo diferente de poder sintácticamente hacer cosas diferentes a la manera de Perl.
En primer lugar, los diccionarios ordenados y las tuplas con nombre se introdujeron en Python 2, pero eso no viene al caso.
No te señalaré los documentos, ya que si estuvieras realmente interesado ya los habrías leído.
La primera diferencia entre los tipos de colección es la mutabilidad. tuple
y el frozenset
son tipos inmutables. Esto significa que pueden ser más eficientes que la list
o el set
.
Si desea algo, puede acceder al azar o en orden, pero cambiará principalmente al final, desea una list
. Si quieres algo que también puedes cambiar al principio, quieres un deque
.
Simplemente no puedes tener tu pastel y también comerlo: cada característica que agregas hace que pierdas algo de velocidad.
dict
y set
son fundamentalmente diferentes de lists
y tuplas`. Almacenan el hash de sus claves, lo que le permite ver si un elemento está en ellas muy rápidamente, pero requiere que la clave sea hashable. No obtienes la misma velocidad de prueba de membresía con listas vinculadas o matrices.
Cuando llega a OrderedDict
y NamedTuple
, está hablando de subclases de los tipos incorporados implementados en Python, en lugar de en C. Son para casos especiales, como cualquier otro código en la biblioteca estándar que tiene que importar . No abarrotan el espacio de nombres, pero es bueno tenerlos cuando los necesite.
Uno de estos días, estarás programando y dirás: "Hombre, ahora sé exactamente lo que significaron con" Debe haber uno, y preferiblemente solo una forma obvia de hacerlo ", un set
es justo lo que necesitaba para esto, ¡estoy tan contento de que sea parte del lenguaje Python! Si tuviera que usar una lista, me llevaría una eternidad ". Ahí es cuando entenderás por qué existen estos diferentes tipos.
Todos estos tipos de datos tienen propósitos diferentes y, en un mundo ideal, podría unirlos más. Sin embargo, en el mundo real necesitamos tener implementaciones eficientes de las colecciones básicas, y por ejemplo, el pedido agrega una penalización de tiempo de ejecución.
Las tuplas nombradas sirven principalmente para hacer que la interfaz de stat () y similares sean más utilizables, y también pueden ser agradables cuando se trata de conjuntos de filas SQL.
La gran unificación que está buscando está realmente allí, en la forma de los diferentes protocolos de acceso (getitem, getattr, iter, ...), que estos tipos se mezclan y combinan para los fines previstos.
Todos estos tipos de recopilación especializados proporcionan funcionalidades específicas que no son proporcionadas de manera adecuada o eficiente por los tipos de datos "estándar" de lista, tupla, dict y conjunto.
Por ejemplo, a veces necesita una colección de artículos únicos y también necesita conservar el orden en el que los encontró. Puede hacer esto utilizando un conjunto para realizar un seguimiento de la membresía y una lista para realizar un seguimiento del orden, pero su solución probablemente será más lenta y más hambrienta de memoria que una estructura de datos especializada diseñada exactamente para este propósito, como un conjunto ordenado.
Estos tipos de datos adicionales, que se ven como combinaciones o variaciones de los básicos, en realidad llenan los vacíos en la funcionalidad que dejan los tipos de datos básicos. Desde una perspectiva práctica, si la biblioteca central o estándar de Python no proporcionara estos tipos de datos, cualquiera que los necesitara inventaría sus propias versiones ineficientes. Se usan con menos frecuencia que los tipos básicos, pero a menudo son suficientes para que valga la pena proporcionar implementaciones estándar.
Un diccionario se indexa por clave (de hecho, es un mapa hash); una lista genérica de tuplas no será. Podría argumentar que ambos deberían implementarse como relaciones, con la capacidad de agregar índices a voluntad, pero en la práctica tener tipos optimizados para los casos de uso comunes es tanto más conveniente como más eficiente.
Se agregan nuevas colecciones especializadas porque son lo suficientemente comunes como para que muchas personas terminen implementándolas utilizando tipos de datos más básicos, y luego tendrías los problemas habituales con la reinvención de la rueda (esfuerzo perdido, falta de interoperabilidad ...). Y si Python acaba de ofrecer un constructo totalmente genérico, tendríamos muchas personas que preguntan "¿Cómo implemento un conjunto usando una relación", etc.?
(por cierto, estoy usando la relación en el sentido matemático o DB)
Una de las cosas que más me gusta de Python es la agilidad. Y una gran cantidad de tipos de colecciones funcionales, eficaces y utilizables me lo dan.
Y todavía hay una forma de hacerlo: cada tipo hace su propio trabajo.