web-dev-qa-db-fra.com

Python 3 trie un dict par ses valeurs

Les seules méthodes que j'ai trouvées fonctionnent pour python2 ou renvoient uniquement une liste de n-uplets.

Est-il possible de trier dictionnaire, par exemple {"aa": 3, "bb": 4, "cc": 2, "dd": 1}, par ses valeurs?

L'ordre du dictionnaire trié que je veux réaliser est du plus grand au plus petit. Je veux que les résultats ressemblent à ceci:

bb 4
aa 3
cc 2
dd 1

Et après le tri, je veux le stocker dans un fichier texte.

58
user2094432

itemgetter (voir d'autres réponses) est (à ma connaissance) plus efficace pour les grands dictionnaires, mais pour le cas courant, je crois que d.get gagne. Et cela ne nécessite pas de supplément import.

>>> d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
>>> s = [(k, d[k]) for k in sorted(d, key=d.get, reverse=True)]
>>> for k, v in s:
...     k, v
...
('bb', 4)
('aa', 3)
('cc', 2)
('dd', 1)

Notez que vous pouvez également définir d.__getitem__ comme key fonction qui peut fournir un léger gain de performances par rapport à d.get.

91
SzieberthAdam
from collections import OrderedDict
from operator import itemgetter    

d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
print(OrderedDict(sorted(d.items(), key = itemgetter(1), reverse = True)))

empreintes

OrderedDict([('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)])

Bien que de votre dernière phrase, il semble qu'une liste de n-uplets fonctionnerait très bien, par exemple.

from operator import itemgetter  

d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
for key, value in sorted(d.items(), key = itemgetter(1), reverse = True):
    print(key, value)

qui imprime

bb 4
aa 3
cc 2
dd 1
27
Paul Draper

Pour trier le dictionnaire, nous pourrions utiliser le module opérateur. Ici est la documentation du module opérateur.

import operator                             #Importing operator module
dc =  {"aa": 3, "bb": 4, "cc": 2, "dd": 1}  #Dictionary to be sorted

dc_sort = sorted(dc.items(),key = operator.itemgetter(1),reverse = True)
print dc_sort

La séquence de sortie sera une liste triée:

[('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)]

Si nous voulons trier par rapport aux clés, nous pouvons utiliser

dc_sort = sorted(dc.items(),key = operator.itemgetter(0),reverse = True)

La séquence de sortie sera:

[('dd', 1), ('cc', 2), ('bb', 4), ('aa', 3)]
8
Reck

Un moyen plus simple (et environ 10% plus rapide) consiste à utiliser une expression lambda

d = {'aa': 3, 'bb': 4, 'cc': 2, 'dd': 1}
s = sorted(d.items(), key=lambda x: x[1], reverse=True)

for k, v in s:
    print(k, v)

Timings

%%timeit Sous CPython 3.7 avec print(k, v) remplacé par pass pour conserver IO).

Réponse acceptée avec d.get ():

1.19 µs ± 16.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Expression lambda:

1.07 µs ± 10.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
4

Vous pouvez trier par valeurs dans ordre inverse (du plus grand au plus petit) en utilisant a compréhension du dictionnaire :

{k: d[k] for k in sorted(d, key=d.get, reverse=True)}
# {'b': 4, 'a': 3, 'c': 2, 'd': 1}

Si vous voulez trier par valeurs dans l'ordre croissant (du plus petit au plus grand)

{k: d[k] for k in sorted(d, key=d.get)}
# {'d': 1, 'c': 2, 'a': 3, 'b': 4}

Si vous voulez trier par les touches par ordre croissant

{k: d[k] for k in sorted(d)}
# {'a': 3, 'b': 4, 'c': 2, 'd': 1}

Cela fonctionne sur CPython 3.6+ et toute implémentation de Python 3.7+ car les dictionnaires conservent l'ordre d'insertion).

2
Boris

Pour trier un dictionnaire et le garder comme un dictionnaire par la suite, vous pouvez utiliser OrderedDict de la bibliothèque standard.

Si ce n'est pas ce dont vous avez besoin, je vous encourage à reconsidérer les fonctions de tri qui vous laisseraient une liste de n-uplets. Quelle sortie voulez-vous, sinon une liste ordonnée de paires clé-valeur (tuples)?

0
Andrew Gorcester