web-dev-qa-db-fra.com

Bon moyen pour initialiser un OrderedDict en utilisant son constructeur de telle 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 conservera-t-elle l'ordre d'une liste de tuples, ou un tuplet de tuples ou un tuplet de listes ou une liste de listes etc. passés au moment de l'initialisation (2ème et 3ème exemple ci-dessus)?

  • Comment peut-on vérifier si OrderedDict maintient effectivement un ordre? Etant donné qu'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 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 préservé. Dans ce cas, j'ai découvert qu'un dict est ordonné par ordre alphabétique, mais ce n'est peut-être pas toujours vrai. Quel est un moyen fiable d'utiliser un contre-exemple pour vérifier si une structure de données conserve l'ordre ou non, à moins d'essayer les vecteurs de test de manière répétée jusqu'à ce que l'un d'eux se casse?

P.S. Je laisserai simplement cela ici pour reference : "Le constructeur OrderedDict et la méthode update () acceptent tous deux les arguments de mots clés, mais leur ordre est perdu car la sémantique de Python utilise des arguments de mot clé de passe utilisant un paramètre non ordonné standard. dictionnaire"

P.P.S: A l'avenir, OrderedDict conservera également l'ordre des kwargs (exemple 1): http://bugs.python.org/issue16991

106
click

OrderedDict préservera toute commande à laquelle il aura accès. Le seul moyen de lui transmettre des données ordonnées pour son initialisation est de transmettre une liste (ou plus généralement une variable) de paires clé-valeur, comme dans vos deux derniers exemples. Comme l'indique la documentation que vous avez liée, OrderedDict n'a accès à aucun ordre lorsque vous passez des arguments de mot clé ou un argument dict, car tout ordre y est supprimé avant que le constructeur OrderedDict ne le voie.

Notez que l'utilisation d'une liste de compréhension 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 de la manière dont il a été créé.

79
BrenBarn
# 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 de la façon dont elle est représentée. Cela vaut également pour la compréhension de liste, la liste générée est identique à celle utilisée pour la fourniture des données (c’est-à-dire que la source provient d’une liste, elle sera déterministe et proviendra de set ou dict pas tellement).

Comment vérifier si OrderedDict maintient effectivement un ordre. Comme un dict a un ordre imprévisible, que se passe-t-il si, heureusement, mes vecteurs de test ont le même ordre initial 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 préservé. Dans ce cas, j'ai découvert qu'un dict est un ordre alphabétique, mais ce n'est peut-être pas toujours vrai. C'est-à-dire un moyen fiable d'utiliser un exemple de compteur pour vérifier si une structure de données conserve l'ordre ou non d'essayer des vecteurs de test de manière répétée jusqu'à ce que l'un d'entre eux se casse.

Vous conservez votre liste de sources de 2-Tuple à titre de référence et vous l'utilisez en tant que données de test pour vos scénarios de test lorsque vous effectuez des tests unitaires. Parcourez-les et assurez-vous que l'ordre est maintenu.

67
metatoaster