Imaginez que vous ayez:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
Quelle est la manière la plus simple de produire le dictionnaire suivant?
a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
python
list
dictionary
Guido
la source
la source
dictionary = {zip(keys, values)}
cela ne fonctionnera pas. Vous devez déclarer explicitement quedict(...)
{thing}
est du sucre syntaxique pour construire unset()
contenant un élément.{*iterable}
est du sucre syntaxique pour construire unset
contenant plusieurs éléments.{k:v}
ou{**mapping}
va construire undict
, mais c'est syntaxiquement assez distinct.{}
pour les dictionnaires. En fait, si nous essayons,type({})
la sortie estdict
. Mais en effet, si nous essayons,type({thing})
la sortie estset
.{k:v for k, v in zip(keys, values)}
. Il s'avère que nous le pouvons. +1.dict
Constructeur le plus performant aveczip
En Python 3, zip renvoie maintenant un itérateur paresseux, et c'est maintenant l'approche la plus performante.
dict(zip(keys, values))
ne nécessite la recherche globale unique pourdict
etzip
, mais il ne forme pas de structures de données intermédiaires inutiles ou n'a pas à traiter les recherches locales dans l'application de fonction.Finaliste, compréhension du dict:
Un finaliste proche de 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):
Choisissez cette option lorsque vous devez mapper ou filtrer en fonction des clés ou de la valeur.
En Python 2,
zip
renvoie une liste, pour éviter de créer une liste inutile, utilisezizip
plutôt (l'alias de zip peut réduire les modifications de code lorsque vous passez à Python 3).Donc ça reste (2.7):
Python 2, idéal pour <= 2.6
izip
fromitertools
devientzip
en Python 3.izip
est meilleur que zip pour Python 2 (car il évite la création de liste inutile), et idéal pour 2.6 ou inférieur:Résultat pour tous les cas:
Dans tous les cas:
Explication:
Si nous regardons l'aide,
dict
nous voyons qu'elle prend une variété d'arguments:L'approche optimale consiste à utiliser un itérable tout en évitant de créer des structures de données inutiles. En Python 2, zip crée une liste inutile:
En Python 3, l'équivalent serait:
et Python 3
zip
crée simplement un objet itérable:Puisque nous voulons éviter de créer des structures de données inutiles, nous voulons généralement éviter celles de Python 2
zip
(car cela crée une liste inutile).Alternatives moins performantes:
Il s'agit d'une expression de générateur transmise au constructeur dict:
ou équivalent:
Et ceci est une compréhension de liste transmise au constructeur de dict:
Dans les deux premiers cas, une couche supplémentaire de calcul non opérationnel (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.
Revue de la performance:
En Python 3.8.2 64 bits fourni par Nix, sur Ubuntu 16.04, ordonné du plus rapide au plus lent:
dict(zip(keys, values))
gagne même avec de petits ensembles de clés et de valeurs, mais pour des ensembles plus grands, les différences de performances deviendront plus importantes.Un intervenant a déclaré:
Nous utilisons
min
parce que ces algorithmes sont déterministes. Nous voulons connaître les performances des algorithmes dans les meilleures conditions possibles.Si le système d'exploitation se bloque pour une raison quelconque, cela n'a rien à voir avec ce que nous essayons de comparer, nous devons donc exclure ce type de résultats de notre analyse.
Si nous l'utilisions
mean
, ce genre d'événements fausserait considérablement nos résultats, et si nous l'utilisions,max
nous n'obtiendrions que le résultat le plus extrême - celui le plus probablement affecté par un tel événement.Un commentateur dit également:
Je suppose que nous voulons dire
dict(zip(...
avec 10 000 nombres aléatoires. Cela ressemble à un cas d'utilisation assez inhabituel. Il est logique que les appels les plus directs dominent dans les grands ensembles de données, et je ne serais pas surpris que les blocages du système d'exploitation dominent étant donné le temps qu'il faudrait pour exécuter ce test, faussant davantage vos chiffres. Et si vous utilisezmean
oumax
je considérerais vos résultats comme dénués de sens.Utilisons une taille plus réaliste sur nos meilleurs exemples:
Et nous voyons ici que
dict(zip(...
cela fonctionne en effet plus rapidement pour les grands ensembles de données d'environ 20%.la source
dict(zip(headList, textList))
& 1,95 \ pm 0,030 microsec pour{k: v for k, v in zip(headList, textList)}
. Je suggère le premier pour la lisibilité et la vitesse. Évidemment, cela arrive à l'argument min () vs mean () pour timeit.min
semble être une mauvaise façon de comparer les performances. Sûrementmean
et / oumax
seraient des indicateurs beaucoup plus utiles pour une utilisation réelle.dict
appel est environ 10% plus rapide.Essaye ça:
En Python 2, il est également plus économique en termes de consommation de mémoire par rapport à
zip
.la source
zip
est déjà économique en consommation de mémoire. docs.python.org/3/library/functions.html#zip En fait, vous pouvez voir quesix
utilisezip
dans Python 3 pour remplaceritertools.izip
dans Python 2 pythonhosted.org/six .la source
Vous pouvez également utiliser des compréhensions de dictionnaire en Python ≥ 2.7:
la source
Une façon plus naturelle consiste à utiliser la compréhension du dictionnaire
la source
dict
objet, pourquoi est-ce ainsi?, merci mec.Si vous devez transformer des clés ou des valeurs avant de créer un dictionnaire, une expression de générateur peut être utilisée. Exemple:
Jetez un oeil Code Like a Pythonista: Idiomatic Python .
la source
avec Python 3.x, opte pour les compréhensions dict
Plus d'informations sur les compréhensions dict ici , un exemple est là:
la source
Pour ceux qui ont besoin de code simple et ne connaissent pas
zip
:Cela peut être fait par une seule ligne de code:
la source
List1
est plus long queList2
for n in range(len(List1))
c'est un anti-patternLa meilleure solution reste:
Transposez-le:
la source
vous pouvez utiliser ce code ci-dessous:
Mais assurez-vous que la longueur des listes sera la même.Si la longueur n'est pas la même, la fonction zip tourne la plus longue.
la source
J'ai eu ce doute alors que j'essayais de résoudre un problème lié au graphique. Le problème que j'avais était que je devais définir une liste de contiguïté vide et que je voulais initialiser tous les nœuds avec une liste vide, c'est à ce moment-là que j'ai pensé que je vérifierais si elle est assez rapide, je veux dire si cela vaudrait la peine de faire une opération zip plutôt qu'une simple paire clé-valeur d'affectation. Après tout, la plupart du temps, le facteur temps est un brise-glace important. J'ai donc effectué l'opération timeit pour les deux approches.
Pour n_nodes = 10 000 000 je reçois,
Itération: 2,825081646999024 Sténographie: 3,535717916001886
Itération: 5.051560923002398 Sténographie: 6.255070794999483
Itération: 6.52859034499852 Sténographie: 8.221581164998497
Itération: 8.683652416999394 Sténographie: 12.599181543999293
Itération: 11.587241565001023 Sténographie: 15.27298851100204
Itération: 14.816342867001367 Sténographie: 17.162912737003353
Itération: 16.645022411001264 Sténographie: 19.976680120998935
Vous pouvez voir clairement après un certain point, l'approche d'itération à la n_ième étape dépasse le temps pris par l'approche abrégée à la n-1_ième étape.
la source
Voici également un exemple d'ajout d'une valeur de liste dans votre dictionnaire
assurez-vous toujours que votre "Clé" (list1) est toujours dans le premier paramètre.
la source
Solution comme compréhension de dictionnaire avec énumérer:
Solution comme pour la boucle avec énumérer:
la source
Vous pouvez également essayer avec une liste qui est une combinaison de deux listes;)
la source
méthode sans fonction zip
la source