Convertir deux listes en un dictionnaire en Python

Imaginez que vous avez:

keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']

Quelle est la façon la plus simple de produire le dictionnaire suivant?

a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
793
demandé sur wim 2008-10-16 23:05:47

12 réponses

comme ceci:

>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}

voilà: -) les paires dict constructeur et zip fonction sont extrêmement utiles: https://docs.python.org/3/library/functions.html#func-dict

1452
répondu Dan Lenski 2018-02-19 14:22:35

essayez ceci:

>>> 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, Il est également plus économique en consommation de mémoire par rapport à zip .

110
répondu Mike Davis 2017-09-13 11:48:23

Imaginez que vous avez:

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')

Quelle est la façon la plus simple de produire le dictionnaire suivant ?

dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}

Plus performantes en - Python 2.7 et 3, dict compréhension:

une amélioration possible sur l'utilisation du constructeur dict est d'utiliser la syntaxe native d'une compréhension dict (pas une compréhension de liste, comme d'autres ont fait erreur le mettre):

new_dict = {k: v for k, v in zip(keys, values)}

en Python 2, zip retourne une liste, pour éviter de créer une liste inutile, utilisez izip à la place (alias à zip peut réduire les changements de code lorsque vous vous déplacez vers Python 3).

from itertools import izip as zip

donc c'est toujours:

new_dict = {k: v for k, v in zip(keys, values)}

Python 2, idéal pour < = 2,6

izip de itertools devient zip en Python 3. izip est mieux que zip pour Python 2 (parce qu'il évite la création inutile de liste), et idéal pour 2.6 ou moins:

from itertools import izip
new_dict = dict(izip(keys, values))

Python 3

en Python 3, zip devient la même fonction que dans le module itertools , donc c'est simplement:

new_dict = dict(zip(keys, values))

une compréhension dict serait cependant plus performante (voir l'évaluation du rendement à la fin de cette réponse).

résultat pour tous les cas:

dans tous les cas:

>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}

explication:

Si l'on regarde l'aide sur dict nous voyons qu'il faut une variété de formes d'arguments:

>>> 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)

l'approche optimale consiste à utiliser un système itérable tout en évitant de créer des structures de données inutiles. En Python 2, zip crée une liste inutile:

>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]

en Python 3, l'équivalent serait:

>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]

et zip de Python 3 crée simplement un objet itérable:

>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>

puisque nous voulons éviter de créer des structures de données inutiles, nous voulons généralement éviter zip de Python 2 (car cela crée une liste inutile).

alternatives moins performantes:

il s'agit d'une expression génératrice transmise au constructeur DCT:

generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)

ou de manière équivalente:

dict((k, v) for k, v in zip(keys, values))

et ceci est une liste de compréhension transmise au constructeur DCT:

dict([(k, v) for k, v in zip(keys, values)])

dans les deux premiers cas, une couche supplémentaire de calcul non opératoire (donc inutile) est placée sur le zip itérable, et dans le cas de la compréhension de liste, une liste supplémentaire est créée inutilement. Je m'attends à tous d'être moins performant, et certainement pas plus.

Performance review:

en python 64 bits 3.4.3, sur Ubuntu 14.04, commandé du plus rapide au plus lent:

>>> 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
91
répondu Aaron Hall 2017-06-02 14:16:17
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}
29
répondu iny 2008-10-16 19:09:18

vous pouvez également utiliser des interprétations de dictionnaires 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'}
26
répondu Brendan Berg 2012-06-10 20:03:34

si vous avez besoin de transformer des clés ou des valeurs avant de créer un dictionnaire, alors une expression génératrice pourrait être utilisée. Exemple:

>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3])) 

jeter un oeil Code Comme un Pythonista: Idiomatiques Python .

13
répondu jfs 2008-10-16 20:45:04

une façon plus naturelle est d'utiliser la compréhension du dictionnaire

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')    
dict = {keys[i]: values[i] for i in range(len(keys))}
10
répondu Polla A. Fattah 2016-04-13 02:07:00

avec Python 3.x, va pour dict interprétations de la

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')

dic = {k:v for k,v in zip(keys, values)}

print(dic)

plus sur dict compréhensions ici , un exemple est là:

>>> print {i : chr(65+i) for i in range(4)}
    {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
9
répondu octoback 2013-05-25 13:47:03

pour ceux qui ont besoin de code simple et ne sont pas familiers avec zip :

List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']

cela peut être fait par une ligne de code:

d = {List1[n]: List2[n] for n in range(len(List1))}
5
répondu exploitprotocol 2013-04-28 15:18:00
  • 2018-04-18

la meilleure solution est encore:

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:

    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')
2
répondu JawSaw 2018-04-18 02:41:00

vous pouvez utiliser ce code ci-dessous:

dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))

Mais assurez-vous que la longueur des listes sera de même.si la longueur n'est pas la même.puis fonction zip turncate la plus longue.

1
répondu Akash Nayak 2017-11-16 13:36:39

méthode sans fonction 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'}
0
répondu xiyurui 2017-05-24 05:47:22