web-dev-qa-db-fra.com

Python OrderedDict ne garde pas l'ordre des éléments

J'essaie de créer un objet OrderedDict mais dès que je le crée, les éléments sont tous mélangés.

C'est ce que je fais:

from collections import OrderedDict
od = OrderedDict({(0,0):[2],(0,1):[1,9],(0,2):[1,5,9]})

Les éléments ne restent pas dans l'ordre que j'attribue

od
OrderedDict([((0, 1), [1, 9]), ((0, 0), [2]), ((0, 2), [1, 5, 9])])

docs.python.org n'a pas d'exemple et je n'arrive pas à comprendre pourquoi la commande se confond. Toute aide est grandement appréciée.

49
Ecolitan

Votre problème est que vous construisez un dict pour donner les données initiales au OrderedDict - ce dict ne le fait pas stocke toute commande, donc la commande est perdue avant d'arriver au OrderedDict.

La solution consiste à construire à partir d'un type de données ordonné - le plus simple étant un list de Tuples:

>>> from collections import OrderedDict
>>> od = OrderedDict([((0, 0), [2]), ((0, 1), [1, 9]), ((0, 2), [1, 5, 9])])
>>> od
OrderedDict([((0, 0), [2]), ((0, 1), [1, 9]), ((0, 2), [1, 5, 9])])

Il convient de noter que c'est pourquoi OrderedDict utilise la syntaxe qu'il utilise pour sa représentation de chaîne - les représentations de chaîne doivent essayer d'être valides Python code pour reproduire l'objet si possible, et c'est pourquoi la sortie utilise une liste de tuples au lieu d'un dict.

Edit: À partir de Python 3.6, kwargs est ordonné , vous pouvez donc utiliser des arguments de mot-clé à la place, à condition que vous soyez à jour Python.

Depuis la version 3.7 , cela est également vrai pour dicts (c'était pour CPython en 3.6, mais la spécification de langue ne le spécifiait pas, donc l'utilisation de OrderedDict était toujours requis pour la compatibilité). Cela signifie que si vous pouvez assumer un environnement 3.7+, vous pouvez souvent supprimer OrderedDict tout à fait, ou en construire un à partir d'un dict régulier si vous avez besoin d'une fonctionnalité spécifique (par exemple: l'ordre est important pour l'égalité) .

91
Gareth Latty