Python 3 ordena un dict por sus valores.

Los únicos métodos que encontré funcionan para python2 o devuelven solo la lista de tuplas.

¿Es posible ordenar el diccionario, por ejemplo, {"aa": 3, "bb": 4, "cc": 2, "dd": 1} , por sus valores?

El orden del diccionario ordenado que quiero lograr es de mayor a menor. Quiero que los resultados se vean así:

 bb 4 aa 3 cc 2 dd 1 

Y después de ordenar, quiero almacenarlo en un archivo de texto.

itemgetter (ver otras respuestas) es (como sé) más eficiente para diccionarios grandes pero para el caso común, creo que d.get gana. Y no requiere una import extra.

 >>> 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) 

Tenga en cuenta que, alternativamente, puede configurar d.__getitem__ como key función key que puede proporcionar un pequeño aumento de rendimiento sobre 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))) 

huellas dactilares

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

Aunque de la última oración, parece que una lista de tuplas funcionaría bien, por ejemplo

 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) 

que imprime

 bb 4 aa 3 cc 2 dd 1 

Para ordenar el diccionario, podríamos hacer uso del módulo operador. Aquí está la documentación del módulo operador.

 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 secuencia de salida será una lista ordenada:

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

Si queremos ordenar con respecto a las claves, podemos hacer uso de

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

La secuencia de salida será:

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

Una forma más simple (y ~ 10% más rápida) es usar una expresión 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) 

Tiempos

%%timeit en CPython 3.7 con print(k, v) sustituida por pass para mantener el IO fuera de la imagen.

Respuesta aceptada usando d.get ():

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

Expresión lambda

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

Para ordenar un diccionario y mantenerlo funcionando como un diccionario después, puede usar OrderedDict de la biblioteca estándar.

Si eso no es lo que necesita, entonces lo aliento a que reconsidere las funciones de clasificación que lo dejan con una lista de tuplas. ¿Qué salida deseaba, si no una lista ordenada de pares clave-valor (tuplas)?

Si desea ordenar por valores en orden inverso (de mayor a menor)

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

Si desea ordenar por valores en orden regular (de menor a mayor)

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

Si quieres ordenar por las teclas en orden regular.

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

Esto funciona en CPython 3.6+ y en cualquier implementación de Python 3.7+ porque los diccionarios mantienen el orden de inserción.