Imaginez que vous avez:
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'}
Comme ça:
>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(Zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}
Le constructeur paire dict
et la fonction Zip
sont extrêmement utiles: https://docs.python.org/3/library/functions.html#func-dict
Essaye ça:
>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Dans Python 2, la consommation de mémoire est également plus économique que Zip
.
Imaginez que vous avez:
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'}
Une amélioration possible de l'utilisation du constructeur dict consiste à utiliser la syntaxe native d'une compréhension dict (et non une compréhension liste, comme d'autres l'ont dit à tort):
new_dict = {k: v for k, v in Zip(keys, values)}
Dans Python 2, Zip
renvoie 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 c'est toujours:
new_dict = {k: v for k, v in Zip(keys, values)}
izip
de itertools
devient Zip
en Python 3. izip
est meilleur que Zip pour Python 2 (car cela évite la création inutile de listes) , et idéal pour 2.6 ou inférieur:
from itertools import izip
new_dict = dict(izip(keys, values))
Dans Python 3, Zip
devient la même fonction que celle contenue dans le module itertools
, de sorte qu'il s'agit simplement:
new_dict = dict(Zip(keys, values))
Une compréhension dictée serait cependant plus performante (voir l’analyse des performances à la fin de cette réponse).
Dans tous les cas:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
Si nous regardons l'aide sur dict
, nous voyons qu'elle prend diverses 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 itératif tout en évitant de créer des structures de données inutiles. Dans Python 2, Zip crée une liste inutile:
>>> Zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
Dans Python 3, l'équivalent serait:
>>> list(Zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
et Python 3's Zip
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 les Zip
de Python 2 2 (car cela crée une liste inutile).
C'est une expression génératrice transmise au constructeur de dict:
generator_expression = ((k, v) for k, v in Zip(keys, values))
dict(generator_expression)
ou équivalent:
dict((k, v) for k, v in Zip(keys, values))
Et ceci est une compréhension de liste transmise au constructeur de dict:
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'attendrais à ce qu'ils soient tous moins performants et certainement pas plus.
En 64 bits Python 3.4.3, sous Ubuntu 14.04, classés 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
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(Zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Vous pouvez également utiliser la compréhension du dictionnaire dans 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'}
Une façon 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, vous pouvez utiliser un expression génératrice . Exemple:
>>> adict = dict((str(k), v) for k, v in Zip(['a', 1, 'b'], [2, 'c', 3]))
Jetez un oeil 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)
Plus sur compréhensions dict ici , un exemple est là:
>>> 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 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))}
La meilleure solution est toujours:
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'}
Le transposer:
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 ce 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.Ensuite, la fonction Zip inverse le plus long.
J'avais ce doute alors que j'essayais de résoudre un problème lié aux graphes. Le problème que j’avais, c’était de définir une liste d’adjacence vide et je voulais initialiser tous les nœuds avec une liste vide; c’est à ce moment-là que j’ai pensé que je vérifiais si c’était assez rapide, mais si cela valait la peine de faire une opération Zip. plutôt que la simple affectation paire clé-valeur. Après tout, le facteur temps est un facteur important pour briser la glace. J'ai donc effectué une opération timeit pour les deux approches.
import timeit
def dictionary_creation(n_nodes):
dummy_dict = dict()
for node in range(n_nodes):
dummy_dict[node] = []
return dummy_dict
def dictionary_creation_1(n_nodes):
keys = list(range(n_nodes))
values = [[] for i in range(n_nodes)]
graph = dict(Zip(keys, values))
return graph
def wrapper(func, *args, **kwargs):
def wrapped():
return func(*args, **kwargs)
return wrapped
iteration = wrapper(dictionary_creation, n_nodes)
shorthand = wrapper(dictionary_creation_1, n_nodes)
for trail in range(1, 8):
print(f'Itertion: {timeit.timeit(iteration, number=trails)}\nShorthand: {timeit.timeit(shorthand, number=trails)}')
Pour n_nodes = 10,000,000 je reçois,
Itération: 2.825081646999024 En abrégé: 3.535717916001886
Itération: 5.051560923002398 En abrégé: 6.255070794999483
Itération: 6.52859034499852 En abrégé: 8.221581164998497
Itération: 8.683652416999394 En abrégé: 12.599181543999293
Itération: 11.587241565001023 En abrégé: 15.27298851100204
Itération: 14.816342867001367 En abrégé: 17.162912737003353
Itération: 16.645022411001264 En abrégé: 19.976680120998935
Vous pouvez clairement voir qu'après un certain point, l'approche itérative à la nième étape dépasse le temps pris par la méthode de la sténographie à la n-1ième étape.
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 "Key" (list1) est toujours dans le premier paramètre.
{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
new_dict = dict(Zip(keys,values))
print(new_dict)
Vous pouvez le faire avec une ligne en utilisant la compréhension du dictionnaire:
a_dict={key:value for key,value in Zip(keys,values)}
et c'est tout. Profiter de Python .....;)
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'}