Convertir deux listes en dictionnaire
-
03-07-2019 - |
Question
Imaginez que vous ayez:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
Quel est le moyen le plus simple de produire le dictionnaire suivant?
a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
La solution
Comme ceci:
>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}
Voila :-) Les constructeurs dict
et zip
par paire sont extrêmement utiles: https://docs.python.org/3/library/functions.html#func-dict
Autres conseils
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, la consommation de mémoire est également plus économique que zip
.
Imaginez que vous ayez:
keys = ('name', 'age', 'food') values = ('Monty', 42, 'spam')
Quel est le moyen le plus simple de produire le dictionnaire suivant?
dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
Le plus performant - Python 2.7 et 3, dict comprehension:
Une amélioration possible sur l'utilisation du constructeur de dict est d'utiliser la syntaxe native d'une compréhension de dict (pas une compréhension de liste, comme d'autres l'ont dit à tort):
new_dict = {k: v for k, v in zip(keys, values)}
Dans Python 2, zip
retourne une liste. Pour éviter de créer une liste inutile, utilisez izip
à la place (un alias de zip peut réduire les modifications de code lorsque vous passez à Python 3).
from itertools import izip as zip
Donc, cela reste:
from itertools import izip
new_dict = dict(izip(keys, values))
Python 2, idéal pour < = 2,6
itertools
de dict
devient <=> en Python 3. <=> est meilleur que zip pour Python 2 (car il évite la création de liste inutile) et idéal pour les versions 2.6 ou inférieures:
new_dict = dict(zip(keys, values))
Python 3
Dans Python 3, <=> devient la même fonction que celle qui figurait dans le module <=>. Il s’agit donc tout simplement de:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
Cependant, une compréhension dictée serait plus performante (voir l’analyse des performances à la fin de cette réponse).
Résultat pour tous les cas:
Dans tous les cas:
>>> 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)
Explication:
Si nous examinons l'aide sur <=>, nous constatons qu'il prend différentes formes d'arguments:
>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
L’approche optimale consiste à utiliser un itératif tout en évitant de créer des structures de données inutiles. Dans Python 2, zip crée une liste inutile:
>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
En Python 3, l'équivalent serait:
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
et celui de Python 3 <=> ne font que créer un objet itérable:
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
Puisque nous voulons éviter de créer des structures de données inutiles, nous voulons généralement éviter le <=> 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 de dict:
dict((k, v) for k, v in zip(keys, values))
ou de manière équivalente:
dict([(k, v) for k, v in zip(keys, values)])
Et ceci est une compréhension de liste transmise au constructeur de dict:
>>> 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
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 la liste, une liste supplémentaire est créée inutilement. Je m'attendrais à ce qu'ils soient tous moins performants et certainement pas plus.
Évaluation des performances:
En Python 3.4.3 64 bits, sur Ubuntu 14.04, classés du plus rapide au plus lent:
<*>>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Vous pouvez également utiliser les compréhensions de dictionnaire en Python & # 8805; 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'}
Une méthode plus naturelle consiste à 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))}
Si vous devez transformer des clés ou des valeurs avant de créer un dictionnaire, utilisez une expression du générateur . peut être utilisé. Exemple:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))
Regardez Code comme un Pythonista: Python idiomatique .
avec Python 3.x, opte pour la compréhension de dict
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dic = {k:v for k,v in zip(keys, values)}
print(dic)
Pour en savoir plus sur les compréhensions dict ici , vous trouverez un exemple:
>>> print {i : chr(65+i) for i in range(4)}
{0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
Pour ceux qui ont besoin de code simple et aren & # 8217; ne connaissez pas zip
:
List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']
Ceci peut être fait avec une ligne de code:
d = {List1[n]: List2[n] for n in range(len(List1))}
- 2018-04-18
La meilleure solution reste:
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'}
Transformez-le:
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')
vous pouvez utiliser le code ci-dessous:
dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))
Mais assurez-vous que la longueur des listes sera la même.Si la longueur n'est pas la même.Alors la fonction zip retourne le plus long.
Voici également un exemple d’ajout d’une valeur de liste dans votre dictionnaire
list1 = ["Name", "Surname", "Age"]
list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
dic = dict(zip(list1, list2))
print(dic)
assurez-vous toujours que votre " clé " (liste1) est toujours dans le premier paramètre.
{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}
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'}