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'}
Était-ce utile?

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'}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top