L'ordre des clés dans les dictionnaires

101

Code:

d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()

print l

Cela imprime ['a', 'c', 'b']. Je ne sais pas comment la méthode keys()détermine l'ordre des mots-clés dans l . Cependant, j'aimerais pouvoir récupérer les mots-clés dans le "bon" ordre. Le bon ordre créerait bien sûr la liste ['a', 'b', 'c'].

rectangle
la source
3
Si les dictionnaires Python sont comme la plupart, ce sont en fait des tables de hachage. Entre autres choses, cela signifie que l'ordre des clés n'est pas garanti ni même spécifié. En particulier, il ne se souviendrait pas de l'ordre dans lequel les clés sont ajoutées.
cHao
3
@cHao: Cela signifie essentiellement que votre programme sera indéterministe si vous bouclez sur les éléments d'un dictionnaire?
HelloGoodbye
4
@HelloGoodbye: je n'irais pas aussi loin; il y a encore là un comportement très prévisible. Chaque itération complète voit exactement une de chaque paire clé / valeur. Et dans la plupart des langues, vous les verrez même dans le même ordre à chaque fois. À moins que les documents ne garantissent une commande particulière, vous ne devriez pas compter sur la commande que vous souhaitez. (Certains langages (comme Perl) vont en fait un peu aléatoire l'ordre - prétendument pour des raisons de sécurité, mais je pense que c'est vraiment juste pour vous débarrasser de l'habitude de vous fier à un comportement non spécifié. :) Je ne pense pas que Python soit tout à fait ce mal, mais hein ...)
cHao
1
L'ordre sera le même à condition que le dict n'ait pas été modifié. Extrait du manuel: "Si items (), keys (), values ​​(), iteritems (), iterkeys () et itervalues ​​() sont appelés sans aucune modification du dictionnaire, les listes correspondent directement. Cela permet la création de paires (valeur, clé) utilisant zip (): paires = zip (d.values ​​(), d.keys ()). "
steveayre
2
@sfranky Je pense que steveayre voulait dire que l'ordre est le même entre ce que vous obtenez en utilisant les différentes méthodes mentionnées, pas le même que l'ordre dans lequel les éléments ont été écrits.
bli

Réponses:

78

Vous pouvez utiliser OrderedDict (nécessite Python 2.7) ou supérieur.

Notez également que OrderedDict({'a': 1, 'b':2, 'c':3})cela ne fonctionnera pas car le que dictvous créez avec {...}a déjà oublié l'ordre des éléments. Au lieu de cela, vous souhaitez utiliser OrderedDict([('a', 1), ('b', 2), ('c', 3)]).

Comme mentionné dans la documentation, pour les versions inférieures à Python 2.7, vous pouvez utiliser cette recette.

Abhinav Gupta
la source
18
Gardez à l'esprit que l'ordre d'un OrderedDict est l' ordre d' insertion ; les clés ne sortiront que par ordre alphabétique si vous les avez insérées de cette façon.
Hugh Bothwell
c'est ce qu'il a montré comme un exemple simplifié; il peut ou non avoir un rapport avec la manière dont il envisage réellement de l'utiliser. J'ai déjà rencontré des personnes qui s'attendaient à ce que OrderedDict renvoie des insertions arbitraires dans un ordre trié, et j'ai donc pensé que je devais le souligner.
Hugh Bothwell
119

Python 3.7+

Dans Python 3.7.0, la nature de préservation de l'ordre d'insertion des dictobjets a été déclarée comme faisant partie officielle de la spécification du langage Python. Par conséquent, vous pouvez en dépendre.

Python 3.6 (CPython)

Depuis Python 3.6, pour l'implémentation CPython de Python, les dictionnaires maintiennent l'ordre d'insertion par défaut. Ceci est cependant considéré comme un détail de mise en œuvre; vous devez toujours l'utiliser collections.OrderedDictsi vous voulez un ordre d'insertion garanti dans d'autres implémentations de Python.

Python> = 2,7 et <3,6

Utilisez la collections.OrderedDictclasse lorsque vous avez besoin d'un dictqui se souvient de l'ordre des éléments insérés.

Eugène Yarmash
la source
49
>>> print sorted(d.keys())
['a', 'b', 'c']

Utilisez la fonction triée , qui trie l'itérable passé.

La .keys()méthode renvoie les clés dans un ordre arbitraire.

Mike Lewis
la source
12
Cela ne fonctionne pas si vous voulez l'ordre d'origine et qu'il n'a pas été trié.
Simon
13

Depuis http://docs.python.org/tutorial/datastructures.html :

"La méthode keys () d'un objet dictionnaire renvoie une liste de toutes les clés utilisées dans le dictionnaire, dans un ordre arbitraire (si vous voulez qu'elle soit triée, appliquez-lui simplement la fonction sorted ())."


la source
12

Triez simplement la liste lorsque vous souhaitez l'utiliser.

l = sorted(d.keys())
A dessiné
la source
1

Bien que l'ordre n'ait pas d'importance car le dictionnaire est hashmap. Cela dépend de l'ordre dans lequel il est inséré:

s = 'abbc'
a = 'cbab'

def load_dict(s):
    dict_tmp = {}
    for ch in s:
        if ch in dict_tmp.keys():
            dict_tmp[ch]+=1
        else:
            dict_tmp[ch] = 1
    return dict_tmp

dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))

sortie:
pour la chaîne abbc, les clés sont dict_keys (['a', 'b', 'c'])
pour la chaîne cbab, les clés sont dict_keys (['c', 'b', 'a'])

zehai
la source
1
Les dictionnaires en python sont commandés par insertion uniquement à partir de la version 3.6+ à vérifier
Crivella