Imagina que tienes:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
¿Cuál es la forma más sencilla de producir el siguiente diccionario?
a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
python
list
dictionary
Guido
fuente
fuente
dictionary = {zip(keys, values)}
eso no funcionará. Tienes que declarar explícitamente comodict(...)
{thing}
es azúcar sintáctico para construir unset()
elemento que contiene un elemento.{*iterable}
Es un azúcar sintáctico para construir un queset
contiene varios elementos.{k:v}
o{**mapping}
va a construir unadict
, pero eso es sintácticamente muy distinta.{}
para los diccionarios. De hecho, si intentamostype({})
la salida esdict
. Pero, de hecho, si lo intentamos,type({thing})
entonces la salida esset
.{k:v for k, v in zip(keys, values)}
. Resulta que podemos. +1.dict
Constructor con más rendimientozip
En Python 3, zip ahora devuelve un iterador perezoso, y este es ahora el enfoque más eficaz.
dict(zip(keys, values))
requiere la búsqueda global de una sola vez paradict
yzip
, pero no forma estructuras de datos intermedias innecesarias ni tiene que lidiar con búsquedas locales en la aplicación de funciones.Segundo puesto, comprensión dict:
Un finalista cercano al uso del constructor dict es usar la sintaxis nativa de una comprensión dict (no una comprensión de lista , como otros lo han expresado erróneamente):
Elija esto cuando necesite asignar o filtrar según las claves o el valor.
En Python 2,
zip
devuelve una lista, para evitar crear una lista innecesaria, useizip
en su lugar (alias a zip puede reducir los cambios de código cuando se mueve a Python 3).Entonces eso sigue siendo (2.7):
Python 2, ideal para <= 2.6
izip
from seitertools
conviertezip
en Python 3.izip
es mejor que zip para Python 2 (porque evita la creación innecesaria de listas), e ideal para 2.6 o menos:Resultado para todos los casos:
En todos los casos:
Explicación:
Si miramos la ayuda
dict
, vemos que toma una variedad de formas de argumentos:El enfoque óptimo es utilizar un iterable evitando crear estructuras de datos innecesarias. En Python 2, zip crea una lista innecesaria:
En Python 3, el equivalente sería:
y Python 3
zip
simplemente crea un objeto iterable:Como queremos evitar crear estructuras de datos innecesarias, generalmente queremos evitar Python 2
zip
(ya que crea una lista innecesaria).Alternativas de menor rendimiento:
Esta es una expresión generadora que se pasa al constructor dict:
o equivalente:
Y esta es una lista de comprensión que se pasa al constructor dict:
En los primeros dos casos, se coloca una capa adicional de cómputo no operativo (por lo tanto innecesario) sobre el zip iterable, y en el caso de la comprensión de la lista, se crea innecesariamente una lista adicional. Esperaría que todos sean menos eficientes, y ciertamente no más.
Revisión de desempeño:
En Python 3.8.2 de 64 bits proporcionado por Nix, en Ubuntu 16.04, ordenado del más rápido al más lento:
dict(zip(keys, values))
gana incluso con pequeños conjuntos de claves y valores, pero para conjuntos más grandes, las diferencias en el rendimiento serán mayores.Un comentarista dijo:
Usamos
min
porque estos algoritmos son deterministas. Queremos conocer el rendimiento de los algoritmos en las mejores condiciones posibles.Si el sistema operativo se bloquea por algún motivo, no tiene nada que ver con lo que estamos tratando de comparar, por lo que debemos excluir ese tipo de resultados de nuestro análisis.
Si lo usáramos
mean
, ese tipo de eventos sesgaría nuestros resultados en gran medida, y si lomax
usáramos solo obtendremos el resultado más extremo, el más probablemente afectado por tal evento.Un comentarista también dice:
Supongo que queremos decir
dict(zip(...
con 10k números aleatorios. Eso suena como un caso de uso bastante inusual. Tiene sentido que las llamadas más directas dominen en grandes conjuntos de datos, y no me sorprendería si los bloqueos del sistema operativo son dominantes dado el tiempo que tomaría ejecutar esa prueba, sesgando aún más sus números. Y si usamean
omax
consideraría sus resultados sin sentido.Usemos un tamaño más realista en nuestros ejemplos principales:
Y vemos aquí que de
dict(zip(...
hecho se ejecuta más rápido para conjuntos de datos más grandes en aproximadamente un 20%.fuente
dict(zip(headList, textList))
& 1.95 \ pm 0.030 microsec para{k: v for k, v in zip(headList, textList)}
. Sugeriría el primero por legibilidad y velocidad. Obviamente, esto llega al argumento min () vs mean () para timeit.min
Parece una mala manera de comparar el rendimiento. Seguramentemean
y / omax
serían indicadores mucho más útiles para el uso real.dict
llamada es aproximadamente un 10% más rápida.Prueba esto:
En Python 2, también es más económico en consumo de memoria en comparación con
zip
.fuente
zip
ya es económico en consumo de memoria. docs.python.org/3/library/functions.html#zip De hecho, puede ver quesix
utilizazip
Python 3 para reemplazaritertools.izip
Python 2 pythonhosted.org/six .fuente
También puede usar las comprensiones de diccionario en Python ≥ 2.7:
fuente
Una forma más natural es utilizar la comprensión del diccionario.
fuente
dict
objeto, ¿por qué es así ?, gracias amigo.Si necesita transformar claves o valores antes de crear un diccionario, se podría usar una expresión generadora . Ejemplo:
Eche un vistazo Código como un Pythonista: Idiomatic Python .
fuente
con Python 3.x, va para comprensiones dict
Más sobre las comprensiones dict aquí , un ejemplo está allí:
fuente
Para aquellos que necesitan un código simple y no están familiarizados con
zip
:Esto se puede hacer con una línea de código:
fuente
List1
es más largo queList2
for n in range(len(List1))
es un antipatrónLa mejor solución sigue siendo:
Tranponerlo:
fuente
puedes usar este código a continuación:
Pero asegúrese de que la longitud de las listas sea la misma. Si la longitud no es la misma. Luego la función zip gira la más larga.
fuente
Tuve esta duda mientras intentaba resolver un problema relacionado con el gráfico. El problema que tuve fue que necesitaba definir una lista de adyacencia vacía y quería inicializar todos los nodos con una lista vacía, fue entonces cuando pensé en comprobar si era lo suficientemente rápido, es decir, si valdría la pena hacer una operación zip en lugar de simple par clave-valor de asignación. Después de la mayoría de las veces, el factor tiempo es un rompehielos importante. Así que realicé la operación timeit para ambos enfoques.
Para n_nodes = 10,000,000 obtengo,
Iteración: 2.825081646999024 Taquigrafía: 3.535717916001886
Iteración: 5.051560923002398 Taquigrafía: 6.255070794999483
Iteración: 6.52859034499852 Abreviatura: 8.221581164998497
Iteración: 8.683652416999394 Taquigrafía: 12.599181543999293
Iteración: 11.587241565001023 Taquigrafía: 15.27298851100204
Iteración: 14.816342867001367 Taquigrafía: 17.162912737003353
Iteración: 16.645022411001264 Taquigrafía: 19.976680120998935
Después de cierto punto, puede ver claramente que el enfoque de iteración en el n-ésimo paso supera el tiempo empleado por el método abreviado en el n-1 ° paso.
fuente
Aquí también hay un ejemplo de cómo agregar un valor de lista en su diccionario
siempre asegúrese de que su "Clave" (lista1) esté siempre en el primer parámetro.
fuente
Solución como comprensión del diccionario con enumerate:
Solución en cuanto a bucle con enumerate:
fuente
También puede probar con una lista que es una combinación de dos listas;)
fuente
método sin función zip
fuente