Converter duas listas em um dicionário
-
03-07-2019 - |
Pergunta
Imagine que você tem:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
O que é a maneira mais simples para produzir o seguinte dicionário?
a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
Solução
Como esta:
>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}
Voila :-) O construtor pares dict
e função zip
são impressionantemente útil: https://docs.python.org/3/library/functions.html#func-dict
Outras dicas
Tente isto:
>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Em Python 2, também é mais econômico no consumo de memória em comparação com zip
.
Imagine que você tem:
keys = ('name', 'age', 'food') values = ('Monty', 42, 'spam')
O que é a maneira mais simples para produzir o seguinte dicionário?
dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
A maioria performance - Python 2.7 e 3, dict compreensão:
Uma possível melhoria em usar o construtor dict é usar a sintaxe nativa de uma compreensão dict (não uma compreensão da lista, como já foi erroneamente colocá-lo):
new_dict = {k: v for k, v in zip(keys, values)}
Em Python 2, zip
retorna uma lista, para evitar a criação de uma lista desnecessário, uso izip
vez (alias para zip pode reduzir alterações de código quando você mover para Python 3).
from itertools import izip as zip
Assim que ainda é:
new_dict = {k: v for k, v in zip(keys, values)}
Python 2, ideal para <= 2,6
izip
de itertools
se torna zip
em Python 3. izip
é melhor do que zip para Python 2 (porque evita a criação desnecessária lista), e ideal para 2.6 ou abaixo:
from itertools import izip
new_dict = dict(izip(keys, values))
Python 3
Em Python 3, zip
se torna a mesma função que estava no módulo itertools
, de modo que é simplesmente:
new_dict = dict(zip(keys, values))
A dict compreensão seria mais performant embora (ver avaliação de desempenho no final desta resposta).
Resultado para todos os casos:
Em todos os casos:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
Explicação:
Se olharmos para a ajuda on dict
vemos que é preciso uma variedade 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)
A abordagem ideal é a utilização de um iteráveis, evitando a criação de estruturas de dados desnecessários. Em Python 2, zip cria uma lista desnecessária:
>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
Em Python 3, o equivalente seria:
>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
zip
e Python 3 apenas cria um objeto iterável:
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
Desde que nós queremos evitar a criação de estruturas de dados desnecessários, que geralmente quer evitar zip
do Python 2 (uma vez que cria uma lista desnecessário).
alternativas de elevada performance Menos:
Este é um gerador de expressão que está sendo passado para o construtor dict:
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
ou equivalentemente:
dict((k, v) for k, v in zip(keys, values))
E esta é uma compreensão da lista que está sendo passado para o construtor dict:
dict([(k, v) for k, v in zip(keys, values)])
Nos dois primeiros casos, uma camada extra de não operativa computação (assim desnecessária) é colocado sobre o iteráveis ??fecho de correr, e, no caso da compreensão da lista, uma lista adicional é desnecessariamente criado. Eu esperaria todos eles para ser menos eficaz, e certamente não mais-lo.
Avaliação de desempenho:
Em 64 bit Python 3.4.3, no Ubuntu 14.04, encomendado mais rápido para o mais 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
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Você também pode usar dicionário compreensões em 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'}
A forma mais natural é usar dicionário compreensão
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dict = {keys[i]: values[i] for i in range(len(keys))}
Se você precisa para transformar chaves ou valores antes de criar um dicionário em seguida, um gerador de expressão poderia ser usado. Exemplo:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))
Dê uma olhada código gosta de uma Pythonista: Idiomatic Python .
com Python 3.x, vale para compreensões dict
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dic = {k:v for k,v in zip(keys, values)}
print(dic)
Mais sobre dict compreensões aqui , um exemplo está lá:
>>> print {i : chr(65+i) for i in range(4)}
{0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
Para aqueles que precisam de código simples e não estão familiarizados com zip
:
List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']
Isto pode ser feito por uma linha de código:
d = {List1[n]: List2[n] for n in range(len(List1))}
- 2018/04/18
A melhor solução ainda é:
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'}
tal transposição lo:
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')
Você pode usar esse código abaixo:
dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))
Mas certifique-se que o comprimento das listas será same.if comprimento não é same.then função zip turncate o mais longo.
Aqui é também um exemplo de adicionar um valor da lista em você dicionário
list1 = ["Name", "Surname", "Age"]
list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
dic = dict(zip(list1, list2))
print(dic)
certifique-se sempre o seu "Key" (list1) é sempre no primeiro parâmetro.
{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}
método sem função 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'}