Dictionnaire Python: les touches () et les valeurs () sont-elles toujours dans le même ordre?

312

Il semble que les listes renvoyées par keys()et les values()méthodes d'un dictionnaire soient toujours un mappage 1 à 1 (en supposant que le dictionnaire n'est pas modifié entre l'appel des 2 méthodes).

Par exemple:

>>> d = {'one':1, 'two': 2, 'three': 3}
>>> k, v = d.keys(), d.values()
>>> for i in range(len(k)):
    print d[k[i]] == v[i]

True
True
True

Si vous ne modifiez pas le dictionnaire entre appel keys()et appel values(), est-il erroné de supposer que la boucle for ci-dessus affichera toujours True? Je n'ai trouvé aucune documentation confirmant cela.

Jason Coon
la source
1
Dans CPython 3.7 (et plus, probablement), vous pouvez vous fier à l'ordre d'itération d'un dictionnaire correspondant à l'ordre d'insertion. mail.python.org/pipermail/python-dev/2017-December/151283.html
BallpointBen
@BallpointBen c'est dans CPython 3.6 et plus et toutes les autres implémentations Python commençant par Python 3.7
Boris

Réponses:

353

Trouvé ceci:

Si items(), keys(), values(), iteritems(), iterkeys(), et itervalues()sont appelés sans modifications intervenant dans le dictionnaire, les listes correspondent directement.

Sur la documentation 2.x et documentation 3.x .

nosklo
la source
5
apparemment, la déclaration dans la documentation 3.x est plus claire: "l'ordre des articles correspondra directement"
Shaohua Li
4
Ce texte est manquant dans la documentation 3.7. Je peux seulement supposer que c'est parce que "Dict garde l'ordre d'insertion" dans 3.7: mail.python.org/pipermail/python-dev/2017-December/151283.html
EliadL
80

Oui, ce que vous avez observé est en effet une propriété garantie - les touches (), les valeurs () et les éléments () renvoient des listes dans un ordre congru si le dict n'est pas modifié. iterkeys () & c itère également dans le même ordre que les listes correspondantes.

Alex Martelli
la source
1
Cependant, si la liste est modifiée, Pandas dataframepropose une alternative où les éléments peuvent être mis à jour ou supprimés, et l'ordre et les emplacements d'index des éléments dans une structure de type dict restent fixes.
Ville
48

Oui, il est garanti en python 2.x :

Si les vues des clés, des valeurs et des éléments sont itérées sans aucune modification intermédiaire du dictionnaire, l'ordre des éléments correspondra directement.

Bjorn
la source
6

Bonnes références aux documents. Voici comment vous pouvez garantir la commande indépendamment de la documentation / mise en œuvre:

k, v = zip(*d.iteritems())
Sassa NF
la source
1
Dans python3.x, utilisez dict.items ()
Good Will
4

Selon http://docs.python.org/dev/py3k/library/stdtypes.html#dictionary-view-objects , les méthodes keys (), values ​​() et items () d'un dict renverront les itérateurs correspondants dont les ordres correspondre. Cependant, je suis incapable de trouver une référence à la documentation officielle de python 2.x pour la même chose.

Donc pour autant que je sache, la réponse est oui, mais uniquement en python 3.0+

sykora
la source
4

Pour ce que ça vaut, un code de production utilisé lourd que j'ai écrit est basé sur cette hypothèse et je n'ai jamais eu de problème avec cela. Je sais que cela ne le rend pas vrai cependant :-)

Si vous ne voulez pas prendre le risque, j'utiliserais iteritems () si vous le pouvez.

for key, value in myDictionary.iteritems():
    print key, value
Koen Bok
la source
-2

Je n'étais pas satisfait de ces réponses car je voulais m'assurer que les valeurs exportées avaient le même ordre, même lors de l'utilisation de différents dictés.

Ici, vous spécifiez l'ordre des clés à l'avance, les valeurs renvoyées auront toujours le même ordre même si le dict change, ou si vous utilisez un dict différent.

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]
jlansey
la source