recorrer - lista dentro de un diccionario python
Convertir dos listas en un diccionario en Python (12)
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''}
Imagina que tienes:
keys = (''name'', ''age'', ''food'') values = (''Monty'', 42, ''spam'')
¿Cuál es la forma más sencilla de producir el siguiente diccionario?
dict = {''name'' : ''Monty'', ''age'' : 42, ''food'' : ''spam''}
Más ejecutante: Python 2.7 y 3, comprensión de dictado:
Una posible mejora en el uso del dict constructor es usar la sintaxis nativa de una comprensión de dictado (no una comprensión de lista, como otros lo han puesto por error):
new_dict = {k: v for k, v in zip(keys, values)}
En Python 2, zip
devuelve una lista, para evitar crear una lista innecesaria, use izip
lugar (con un alias para zip puede reducir los cambios de código cuando te mueves a Python 3).
from itertools import izip as zip
Así que eso sigue siendo:
new_dict = {k: v for k, v in zip(keys, values)}
Python 2, ideal para <= 2.6
itertools
from itertools
convierte en zip
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 más abajo:
from itertools import izip
new_dict = dict(izip(keys, values))
Python 3
En Python 3, zip
convierte en la misma función que estaba en el módulo itertools
, por lo que es simplemente:
new_dict = dict(zip(keys, values))
Sin embargo, una comprensión del dict sería más eficaz (vea la revisión de desempeño al final de esta respuesta).
Resultado para todos los casos:
En todos los casos:
>>> new_dict
{''age'': 42, ''name'': ''Monty'', ''food'': ''spam''}
Explicación:
Si nos fijamos en la ayuda en dict
, vemos que toma una variedad de formas de argumentos:
>>> help(dict)
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object''s
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| dict(**kwargs) -> new dictionary initialized with the name=value pairs
| in the keyword argument list. For example: dict(one=1, two=2)
El enfoque óptimo es utilizar un iterable mientras se evita crear estructuras de datos innecesarias. En Python 2, zip crea una lista innecesaria:
>>> zip(keys, values)
[(''name'', ''Monty''), (''age'', 42), (''food'', ''spam'')]
En Python 3, el equivalente sería:
>>> list(zip(keys, values))
[(''name'', ''Monty''), (''age'', 42), (''food'', ''spam'')]
y el zip
Python 3 simplemente crea un objeto iterable:
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
Como queremos evitar crear estructuras de datos innecesarias, generalmente queremos evitar el zip
Python 2 (ya que crea una lista innecesaria).
Alternativas de menor rendimiento:
Esta es una expresión generadora que se pasa al constructor dict:
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
o equivalente:
dict((k, v) for k, v in zip(keys, values))
Y esta es una lista de comprensión que se pasa al constructor de dict:
dict([(k, v) for k, v in zip(keys, values)])
En los dos primeros 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. Espero que todos ellos sean menos eficaces, y ciertamente no más.
Revisión del desempeño:
En Python 3.4.3 de 64 bits, en Ubuntu 14.04, ordenado de más rápido a más lento:
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
0.7836067057214677
>>> min(timeit.repeat(lambda: dict(zip(keys, values))))
1.0321204089559615
>>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
1.0714934510178864
>>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
1.6110592018812895
>>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
1.7361853648908436
Me gusta esto:
>>> keys = [''a'', ''b'', ''c'']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{''a'': 1, ''b'': 2, ''c'': 3}
Voila :-) El constructor de dict
pares y la función zip
son increíblemente útiles: https://docs.python.org/3/library/functions.html#func-dict
Para aquellos que necesitan un código simple y no están familiarizados con zip
:
List1 = [''This'', ''is'', ''a'', ''list'']
List2 = [''Put'', ''this'', ''into'', ''dictionary'']
Esto se puede hacer por una línea de código:
d = {List1[n]: List2[n] for n in range(len(List1))}
Prueba esto:
>>> import itertools
>>> keys = (''name'', ''age'', ''food'')
>>> values = (''Monty'', 42, ''spam'')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{''food'': ''spam'', ''age'': 42, ''name'': ''Monty''}
En Python 2, también es más económico en el consumo de memoria en comparación con el zip
.
Puedes usar el siguiente código:
dict(zip([''name'', ''age'', ''food''], [''Monty'', 42, ''spam'']))
Pero asegúrese de que la longitud de las listas sea la misma. Si la longitud no es la misma, la función zip alternará con la más larga.
Si necesita transformar claves o valores antes de crear un diccionario, se puede usar una expresión generadora . Ejemplo:
>>> adict = dict((str(k), v) for k, v in zip([''a'', 1, ''b''], [2, ''c'', 3]))
Echa un vistazo a Code Like a Pythonista: Idiomatic Python .
También puede usar las comprensiones de diccionarios en Python ≥ 2.7:
>>> keys = (''name'', ''age'', ''food'')
>>> values = (''Monty'', 42, ''spam'')
>>> {k: v for k, v in zip(keys, values)}
{''food'': ''spam'', ''age'': 42, ''name'': ''Monty''}
Una forma más natural es utilizar la comprensión del diccionario.
keys = (''name'', ''age'', ''food'')
values = (''Monty'', 42, ''spam'')
dict = {keys[i]: values[i] for i in range(len(keys))}
con Python 3.x, va para las comprensiones de dictado
keys = (''name'', ''age'', ''food'')
values = (''Monty'', 42, ''spam'')
dic = {k:v for k,v in zip(keys, values)}
print(dic)
Más sobre dictámenes aquí , un ejemplo está ahí:
>>> print {i : chr(65+i) for i in range(4)}
{0 : ''A'', 1 : ''B'', 2 : ''C'', 3 : ''D''}
método sin función zip
l1 = {1,2,3,4,5}
l2 = {''a'',''b'',''c'',''d'',''e''}
d1 = {}
for l1_ in l1:
for l2_ in l2:
d1[l1_] = l2_
l2.remove(l2_)
break
print (d1)
{1: ''d'', 2: ''b'', 3: ''e'', 4: ''a'', 5: ''c''}
>>> keys = (''name'', ''age'', ''food'')
>>> values = (''Monty'', 42, ''spam'')
>>> dict(zip(keys, values))
{''food'': ''spam'', ''age'': 42, ''name'': ''Monty''}
- 2018-04-18
La mejor solución sigue siendo:
In [92]: keys = (''name'', ''age'', ''food'')
...: values = (''Monty'', 42, ''spam'')
...:
In [93]: dt = dict(zip(keys, values))
In [94]: dt
Out[94]: {''age'': 42, ''food'': ''spam'', ''name'': ''Monty''}
Tranpose it:
lst = [(''name'', ''Monty''), (''age'', 42), (''food'', ''spam'')]
keys, values = zip(*lst)
In [101]: keys
Out[101]: (''name'', ''age'', ''food'')
In [102]: values
Out[102]: (''Monty'', 42, ''spam'')