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.
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
.
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
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)]
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)
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).
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)?