Comment récupérer les éléments d’un dictionnaire dans l’ordre dans lequel ils sont insérés ?

StackOverflow https://stackoverflow.com/questions/60848

  •  09-06-2019
  •  | 
  •  

Question

Est-il possible de récupérer les éléments d'un dictionnaire Python dans l'ordre dans lequel ils ont été insérés ?

Était-ce utile?

La solution

Le Python standard dict le fait par défaut si vous utilisez CPython 3.6+ (ou Python 3.7+ pour toute autre implémentation de Python).

Sur les anciennes versions de Python, vous pouvez utiliser collections.OrderedDict.

Autres conseils

Les autres réponses sont correctes ;ce n'est pas possible, mais vous pouvez l'écrire vous-même.Cependant, au cas où vous ne sauriez pas comment implémenter quelque chose comme ça, voici une implémentation complète et fonctionnelle qui sous-classe le dict que je viens d'écrire et de tester.(Notez que l'ordre des valeurs transmises au constructeur n'est pas défini mais viendra avant les valeurs transmises plus tard, et vous pouvez toujours ne pas autoriser l'initialisation des dictionnaires ordonnés avec des valeurs.)

class ordered_dict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self._order = self.keys()

    def __setitem__(self, key, value):
        dict.__setitem__(self, key, value)
        if key in self._order:
            self._order.remove(key)
        self._order.append(key)

    def __delitem__(self, key):
        dict.__delitem__(self, key)
        self._order.remove(key)

    def order(self):
        return self._order[:]

    def ordered_items(self):
        return [(key,self[key]) for key in self._order]


od = ordered_dict()
od["hello"] = "world"
od["goodbye"] = "cruel world"
print od.order()            # prints ['hello', 'goodbye']

del od["hello"]
od["monty"] = "python"
print od.order()            # prints ['goodbye', 'monty']

od["hello"] = "kitty"
print od.order()            # prints ['goodbye', 'monty', 'hello']

print od.ordered_items()
# prints [('goodbye','cruel world'), ('monty','python'), ('hello','kitty')]

Utilisez OrderedDict(), disponible depuis la version 2.7

Juste une question de curiosité :

from collections import OrderedDict
a = {}
b = OrderedDict()
c = OredredDict()

a['key1'] = 'value1'
a['key2'] = 'value2'

b['key1'] = 'value1'
b['key2'] = 'value2'

c['key2'] = 'value2'
c['key1'] = 'value1'

print a == b #True
print a == c #True
print b == c #False

Ou faites simplement de la clé un tuple avec time.now() comme premier champ du tuple.

Ensuite, vous pouvez récupérer les clés avec dictname.keys(), trier et le tour est joué !

Gerry

Depuis Python 3.7, le dict standard préserve l'ordre d'insertion.Du documents:

Modifié dans la version 3.7 :L’ordre du dictionnaire est garanti comme étant l’ordre d’insertion.Ce comportement était un détail d'implémentation de CPython à partir de 3.6.

Ainsi, vous devriez pouvoir parcourir le dictionnaire normalement ou utiliser popitem().

Vous ne pouvez pas faire cela avec la classe de base dict - elle est classée par hachage.Vous pouvez créer votre propre dictionnaire qui est en réalité une liste de paires clé, valeur ou autre, qui seraient ordonnées.

J'ai déjà utilisé StableDict avec succès.

http://pypi.python.org/pypi/StableDict/0.2

Ou utilisez l'une des implémentations pour le PEP-372 décrit ici, comme le module dict du pythonutils.

J'ai utilisé avec succès l'implémentation de pocoo.org, c'est aussi simple que de remplacer votre

my_dict={}
my_dict["foo"]="bar"

avec

my_dict=odict.odict()
my_dict["foo"]="bar"

et exigent juste ce fichier

Ce n'est possible que si vous stockez les clés dans une liste distincte pour les référencer ultérieurement.

Ce que vous pouvez faire est d'insérer les valeurs avec une clé représentant l'ordre saisi, puis d'appeler sorted() sur les articles.

>>> obj = {}
>>> obj[1] = 'Bob'
>>> obj[2] = 'Sally'
>>> obj[3] = 'Joe'
>>> for k, v in sorted(obj.items()):
...     print v
... 
Bob
Sally
Joe
>>> 

si vous n'avez pas besoin de la fonctionnalité dict et que vous devez uniquement renvoyer les tuples dans l'ordre dans lequel vous les avez insérés, une file d'attente ne fonctionnerait-elle pas mieux ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top