J'ai ceci:
d1 = OrderedDict([('a', '1'), ('b', '2')])
Si je fais ceci:
d1.update({'c':'3'})
Ensuite, je reçois ceci:
OrderedDict([('a', '1'), ('b', '2'), ('c', '3')])
mais je veux ceci:
[('c', '3'), ('a', '1'), ('b', '2')]
sans créer de nouveau dictionnaire.
python
python-3.x
dictionary
python-2.x
ordereddict
user2392209
la source
la source
Réponses:
Il n'y a pas de méthode intégrée pour faire cela dans Python 2. Si vous en avez besoin, vous devez écrire une
prepend()
méthode / fonction qui opère sur lesOrderedDict
internes avec une complexité O (1).Python 3.2 et versions ultérieures, vous devez utiliser la
move_to_end
méthode. La méthode accepte unlast
argument qui indique si l'élément sera déplacé vers le bas (last=True
) ou vers le haut (last=False
) duOrderedDict
.Enfin, si vous voulez une solution rapide, sale et lente , vous pouvez simplement en créer une nouvelle à
OrderedDict
partir de zéro.Détails des quatre solutions différentes:
Étendre
OrderedDict
et ajouter une nouvelle méthode d'instanceDémo:
Fonction autonome qui manipule les
OrderedDict
objetsCette fonction fait la même chose en acceptant l'objet, la clé et la valeur dict. Personnellement, je préfère la classe:
Démo:
Utiliser
OrderedDict.move_to_end()
(Python> = 3.2)Python 3.2 a introduit la
OrderedDict.move_to_end()
méthode. En l'utilisant, nous pouvons déplacer une clé existante à l'une ou l'autre extrémité du dictionnaire en temps O (1).Si nous avons besoin d'insérer un élément et de le déplacer vers le haut, le tout en une seule étape, nous pouvons directement l'utiliser pour créer un
prepend()
wrapper (non présenté ici).Créez un nouveau
OrderedDict
- lent !!!Si vous ne voulez pas faire cela et que les performances ne sont pas un problème, le moyen le plus simple est de créer un nouveau dict:
production:
la source
c
existe déjà, cela ne mettra pas à jour l'ancienne valeurmove_to_end
il n'y a pas de balise Python 3 sur la question,move_to_end
ne fonctionne que dans Python 3.2+. Je mettrai à jour ma réponse pour inclure la solution basée sur Python 3. Merci beaucoup pour la mise à jour!move_to_front
, il vaut peut-être mieux implémenter unemove_to_front
méthode au lieu d'uneprepend
méthode séparée ? Cela rendra votre code plus portable si jamais vous avez besoin de prendre en charge à la fois Python 2 et Python 3 à partir de la même base de code.dict_setitem=dict.__setitem__
tant que paramprepend
? Pourquoi passerait / devrait-on passer un passeur différent?ordered_dict_prepend
ci - dessus. Appelerordered_dict_prepend(d, 'c', 100)
deux fois et essayer d'imprimer le dict résultant (en entrant simplement dansd
la console de Python) entraîne le processus Python qui continue à saisir la mémoire. Testé avec Python 2.7.10EDIT (2019-02-03) Notez que la réponse suivante ne fonctionne que sur les anciennes versions de Python. Plus récemment,
OrderedDict
a été réécrit en C. En outre, cela touche les attributs de double soulignement qui sont mal vus.Je viens d'écrire une sous-classe de
OrderedDict
dans un de mes projets dans un but similaire. Voici l'essentiel .Les opérations d'insertion sont également à temps constant
O(1)
(elles ne nécessitent pas de reconstruction de la structure de données), contrairement à la plupart de ces solutions.la source
TypeError: '_Link' object does not support indexing
en utilisant ceci sur Python 3.4.OrderedDict
a été réécrit en C à partir de Python 3.5, et cette sous-classe a commis le tabou de se débrouiller avec les internes (en fait, inverser la modification des noms pour accéder aux propriétés __).Vous devez créer une nouvelle instance de
OrderedDict
. Si vos clés sont uniques:Mais sinon, méfiez-vous car ce comportement peut ou non être souhaité pour vous:
la source
OrderedDict
instable?Si vous savez que vous voudrez une clé «c», mais que vous ne connaissez pas la valeur, insérez «c» avec une valeur factice lorsque vous créez le dict.
et modifiez la valeur ultérieurement.
la source
C'est désormais possible avec move_to_end (key, last = True)
https://docs.python.org/3/library/collections.html#collections.OrderedDict.move_to_end
la source
FWIW Voici un code quick-n-dirty que j'ai écrit pour l'insertion dans une position d'index arbitraire. Pas nécessairement efficace mais cela fonctionne sur place.
la source
Vous voudrez peut-être utiliser une structure complètement différente, mais il existe des moyens de le faire en python 2.7 .
d2 contiendra alors
Comme mentionné par d'autres, en python 3.2, vous pouvez utiliser
OrderedDict.move_to_end('c', last=False)
pour déplacer une clé donnée après l'insertion.la source
Si vous avez besoin de fonctionnalités qui ne sont pas là, étendez simplement la classe avec ce que vous voulez:
Pas très efficace, mais fonctionne:
la source
Je suggérerais d'ajouter une
prepend()
méthode à cette pure recette Python ActiveState ou d'en dériver une sous-classe. Le code pour ce faire pourrait être assez efficace étant donné que la structure de données sous-jacente pour le classement est une liste chaînée.Mettre à jour
Pour prouver que cette approche est faisable, vous trouverez ci-dessous un code qui fait ce qui est suggéré. En prime, j'ai également apporté quelques modifications mineures supplémentaires pour pouvoir travailler à la fois dans Python 2.7.15 et 3.7.1.
Une
prepend()
méthode a été ajoutée à la classe dans la recette et a été implémentée en termes d'une autre méthode qui a été ajoutée nomméemove_to_end()
, qui a été ajoutéeOrderedDict
dans Python 3.2.prepend()
peut également être implémenté directement, presque exactement comme indiqué au début de la réponse de @Ashwini Chaudhary - et cela entraînerait probablement une légère accélération, mais cela a été laissé comme un exercice pour le lecteur motivé ...la source
J'ai eu une boucle à l'infini en essayant d'imprimer ou d'enregistrer le dictionnaire en utilisant la réponse @Ashwini Chaudhary avec Python
2.7
. Mais j'ai réussi à réduire un peu son code et je l'ai fait fonctionner ici:la source
C'est un dict ordonné par défaut qui permet d'insérer des éléments dans n'importe quelle position et d'utiliser le. opérateur pour créer des clés:
la source