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:
Est-ce qu'une
OrderedDict
conservation de l'ordre d'une liste de tuples, ou d'un tuple de tuples ou d'un tuple de listes ou d'une liste de listes etc. passée au moment de l'initialisation (2ème et 3ème exemple ci-dessus)?Comment vérifier si
OrderedDict
une commande est effectivement maintenue? Puisque adict
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 d'd = OrderedDict({'b':2, 'a':1})
écrired = OrderedDict({'a':1, 'b':2})
, je peux conclure à tort que l'ordre est conservé. Dans ce cas, j'ai découvert que adict
est classé 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 préserve l'ordre ou non, à moins d'essayer des vecteurs de test à plusieurs reprises jusqu'à ce que l'on casse?
PS Je vais juste laisser ceci ici pour référence : "Le constructeur OrderedDict et la méthode update () acceptent tous les deux des arguments de mots-clés, mais leur ordre est perdu car la fonction de Python appelle les arguments de mots-clés de la sémantique à l'aide d'un dictionnaire non ordonné régulier."
PPS: J'espère qu'à l'avenir, OrderedDict conservera également l'ordre des kwargs (exemple 1): http://bugs.python.org/issue16991
la source
OrderDict(b=2, a=1)
c'est aussi un bon moyen. Voir PEP 468 .Réponses:
OrderedDict conservera toute commande à laquelle il a accès. La seule façon de lui passer des données ordonnées à initialiser est de passer une liste (ou, plus généralement, un itérable) de paires clé-valeur, comme dans vos deux derniers exemples. Comme le dit 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 compréhension de liste dans votre dernier exemple ne change rien. Il n'y a aucune différence entre
OrderedDict([(i,i) for i in l])
etOrderedDict([('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 façon dont il a été créé.la source
Oui, cela fonctionnera. Par définition, une liste est toujours ordonnée de la manière dont 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 que la source d'une liste sera déterministe, issue d'un
set
oudict
pas tellement).Vous conservez votre liste source de 2-tuple pour référence et vous l'utilisez comme données de test pour vos cas de test lorsque vous effectuez des tests unitaires. Parcourez-les et assurez-vous que l'ordre est maintenu.
la source
__hash__
. Plus précisément sur lestr
type.OrderedDict
afin de ne pas avoir la charge de convertir une liste en fichierOrderedDict
. Je fais une boucle sur les éléments comme une liste au lieu d'un dictionnaire.