Bonne façon d'initialiser un OrderedDict en utilisant son constructeur de sorte qu'il conserve l'ordre des données initiales?

Quelle est la bonne façon d'initialiser un dictionnaire ordonné (OD) afin qu'il conserve l'ordre des données initiales?

from collections import OrderedDict

# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1}) 

# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])

# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])

Question:

  • Une OrderedDict conserver l'ordre d'une liste de tuples, ou tuple de tuples ou tuple de listes ou d'une liste de listes, etc. passé au moment de l'initialisation (2ème et 3ème exemple ci-dessus)?

  • Comment va-t-on vérifier si OrderedDict maintient réellement une commande? Comme un dict a un ordre imprévisible, et si mon test vecteurs heureusement, ont le même ordre que l'ordre imprévisible d'un dict? Par exemple, si au lieu de d = OrderedDict({'b':2, 'a':1}) j'écris d = OrderedDict({'a':1, 'b':2}), je peux conclure, à tort, que l'ordre est conservé. Dans ce cas, j'ai découvert qu'un dict est classé par ordre alphabétique, mais cela peut ne pas être toujours vrai. Quel est un moyen fiable d'utiliser un contre-exemple pour vérifier si une structure de données préserve l'ordre ou non, à moins d'essayer des vecteurs de test à plusieurs reprises jusqu'à ce qu'on se casse?

P.S. Je vais laisser ça ici pour reference : "le constructeur OrderedDict et la méthode update() acceptent tous les deux des arguments de mot-clé, mais leur ordre est perdu parce que les arguments de mot-clé pass-in de sémantique d'appel de fonction de Python utilisent un dictionnaire non ordonné régulier"

P. P. S: espérons qu'à L'avenir, OrderedDict préservera également l'ordre des kwargs (exemple 1): http://bugs.python.org/issue16991

77
demandé sur smci 2014-08-25 10:25:39

2 réponses

Le OrderedDict conservera tout ordre auquel il a accès. La seule façon de lui transmettre des données ordonnées à initialiser est de passer une liste (ou, plus généralement, une itérable) de paires clé-valeur, comme dans vos deux derniers exemples. Comme le dit la documentation à laquelle vous avez lié, OrderedDict n'a accès à aucun ordre lorsque vous passez des arguments de mots clés ou un argument dict, car tout ordre y est supprimé avant que le constructeur OrderedDict ne le voit.

Notez que l'utilisation d'une compréhension de liste dans votre dernier exemple ne change rien. Il n'y a pas de différence entre OrderedDict([(i,i) for i in l]) et OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')]). La compréhension de la liste est évaluée et crée la liste et elle est transmise; OrderedDict ne sait rien sur la façon dont elle a été créée.

64
répondu BrenBarn 2014-08-25 06:35:05
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b', 2), ('a', 1)])

Oui, ça va marcher. Par définition, une liste est toujours ordonnée comme elle est représentée. Cela vaut aussi pour la compréhension de liste, la liste générée est de la même manière que les données ont été fournies (c'est-à-dire source d'une liste, elle sera déterministe, provenant d'un set ou dict pas tellement).

Comment va-t-on vérifier si OrderedDict maintient réellement une commande. Comme un dict a un ordre imprévisible, que se passe-t-il si mes Vecteurs de test ont heureusement le même ordre initial que le ordre imprévisible d'un dict?. Par exemple, si au lieu de d = OrderedDict({'b':2, 'a':1}) j'écris d = OrderedDict({'a':1, 'b':2}), je peux conclure, à tort, que l'ordre est conservé. Dans ce cas, j'ai découvert qu'un dict est classé par ordre alphabétique, mais cela peut ne pas être toujours vrai. c'est-à-dire quel est un moyen fiable d'utiliser un contre-exemple pour vérifier si une structure de données préserve l'ordre ou pas à court d'essayer des vecteurs de test à plusieurs reprises jusqu'à ce que l'on se casse.

Vous gardez votre liste source de 2-tuple pour référence, et utilisez-la comme test données pour vos cas de test lorsque vous effectuez des tests unitaires. Parcourez-les et assurez-vous que l'ordre est maintenu.

51
répondu metatoaster 2014-08-25 06:34:33