¿Cómo ordeno un diccionario por valor?


Tengo un diccionario de valores leídos de dos campos en una base de datos: un campo de cadena y un campo numérico. El campo string es único, por lo que es la clave del diccionario.

Puedo ordenar por las claves, pero ¿cómo puedo ordenar en función de los valores?

Nota: He leído la pregunta de desbordamiento de pila ¿Cómo puedo ordenar una lista de diccionarios por valores del diccionario en Python? y probablemente podría cambiar mi código para tener una lista de diccionarios, pero ya que realmente no necesito una lista de diccionarios que quería saber si hay una solución más simple.

Author: Peter Mortensen, 2009-03-05

30 answers

No es posible ordenar un diccionario, solo para obtener una representación de un diccionario que está ordenado. Los diccionarios son inherentemente sin orden, pero otros tipos, como listas y tuplas, no lo son. Por lo tanto, necesita un tipo de datos ordenado para representar valores ordenados, que será una lista, probablemente una lista de tuplas.

Por ejemplo,

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x será una lista de tuplas ordenadas por el segundo elemento en cada tupla. dict(sorted_x) == x.

Y para aquellos que deseen ordenar en las teclas en lugar de valores:

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

En Python3 ya que el desembalaje no está permitido [1] podemos usar

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_by_value = sorted(x.items(), key=lambda kv: kv[1])
 3642
Author: Devin Jeanpierre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-22 17:20:24

Tan simple como: sorted(dict1, key=dict1.get)

Bueno, en realidad es posible hacer un "ordenar por valores de diccionario". Recientemente tuve que hacer eso en un Golf de Código (Pregunta de desbordamiento de pilaCódigo golf: Carta de frecuencia de la palabra). Resumido, el problema era del tipo: dado un texto, contar con qué frecuencia se encuentra cada palabra y mostrar una lista de las palabras principales, ordenadas por frecuencia decreciente.

Si construyes un diccionario con las palabras como claves y el número de ocurrencias de cada palabra como valor, simplificado aquí como:

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
  d[w] += 1

Luego puede obtener una lista de las palabras, ordenadas por frecuencia de uso con sorted(d, key=d.get) - el orden itera sobre las claves del diccionario, usando el número de ocurrencias de palabras como una clave de orden .

for w in sorted(d, key=d.get, reverse=True):
  print w, d[w]

Estoy escribiendo esta explicación detallada para ilustrar lo que la gente a menudo quiere decir con "Puedo ordenar fácilmente un diccionario por clave, pero cómo ordenar por valor" - y creo que el OP estaba tratando de abordar este problema. Y la solución es hacer tipo de lista de la claves, basadas en los valores, como se muestra arriba.

 990
Author: Nas Banov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36

Podrías usar:

sorted(d.items(), key=lambda x: x[1])

Esto ordenará el diccionario por los valores de cada entrada dentro del diccionario de menor a mayor.

 618
Author: Mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-05 08:06:08

Los dictados no se pueden ordenar, pero puede crear una lista ordenada a partir de ellos.

Una lista ordenada de valores dict:

sorted(d.values())

Una lista de pares (clave, valor), ordenados por valor:

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
 171
Author: Roberto Bonvallet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-16 17:26:10

En Python 2.7, tenemos el nuevo tipo OrderedDict, que recuerda el orden en el que se agregaron los elementos.

>>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}

>>> for k, v in d.items():
...     print "%s: %s" % (k, v)
...
second: 2
fourth: 4
third: 3
first: 1

>>> d
{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}

Para hacer un nuevo diccionario ordenado a partir del original, ordenando por los valores:

>>> from collections import OrderedDict
>>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))

El OrderedDict se comporta como un dict normal:

>>> for k, v in d_sorted_by_value.items():
...     print "%s: %s" % (k, v)
...
first: 1
second: 2
third: 3
fourth: 4

>>> d_sorted_by_value
OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])
 132
Author: mykhal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-03 16:59:39

ACTUALIZACIÓN: 5 DE DICIEMBRE DE 2015 usando Python 3.5

Aunque encontré útil la respuesta aceptada, también me sorprendió que no se haya actualizado a referencia OrderedDict desde la biblioteca estándar colecciones módulo como una alternativa viable y moderna - diseñado para resolver exactamente este tipo de problema.

from operator import itemgetter
from collections import OrderedDict

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

El funcionario OrderedDict la documentación también ofrece un ejemplo muy similar, pero usando una lambda para ordenar función:

# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
 77
Author: arcseldon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 05:54:53

A menudo puede ser muy útil de usar namedtuple. Por ejemplo, tienes un diccionario de' name 'como claves y 'score' como valores y quieres ordenar en 'score':

import collections
Player = collections.namedtuple('Player', 'score name')
d = {'John':5, 'Alex':10, 'Richard': 7}

Ordenando primero con la puntuación más baja:

worst = sorted(Player(v,k) for (k,v) in d.items())

Ordenando primero con la puntuación más alta:

best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)

Ahora puedes obtener el nombre y la puntuación de, digamos, el segundo mejor jugador (índice=1) muy pitónicamente así:

player = best[1]
player.name
    'Richard'
player.score
    7
 66
Author: Remi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-24 02:11:59

Más o menos lo mismo que la respuesta de Hank Gay;


    sorted([(value,key) for (key,value) in mydict.items()])

O optimizado un poco como sugiere John Fouhy;


    sorted((value,key) for (key,value) in mydict.items())

 59
Author: user26294,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-09 14:36:18

A partir de Python 3.6 el dictado incorporado se ordenará

Buenas noticias, por lo que el caso de uso original de la OP de asignar pares recuperados de una base de datos con identificadores de cadena únicos como claves y valores numéricos como valores en un diccionario Python v3.6+ incorporado, ahora debe respetar el orden de inserción.

If diga las expresiones de tabla de dos columnas resultantes de una consulta de base de datos como:

SELECT a_key, a_value FROM a_table ORDER BY a_value;

Se almacenaría en dos tuplas de Python, k_seq y v_seq (alineadas por índice numérico y con la misma duración por supuesto), entonces:

k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(zip(k_seq, v_seq))

Permitir a la salida más tarde como:

for k, v in ordered_map.items():
    print(k, v)

Cediendo en este caso (para el nuevo diccionario incorporado de Python 3.6+!):

foo 0
bar 1
baz 42

En el mismo orden por valor de v.

Donde en la instalación de Python 3.5 en mi máquina produce actualmente:

bar 1
foo 0
baz 42

Detalles:

Como propuso en 2012 Raymond Hettinger (cf. correo en python - dev con asunto "Diccionarios más compactos con iteración más rápida") y ahora (en 2016) anunciado en un correo por Victor Stinner a python - dev con subject "Python 3.6 dict becomes compact and gets a private version; and keywords becomed ordered" debido a la corrección/implementación del problema 27350 "Compact and ordered dict" en Python 3.6 ahora podremos usar un dict incorporado para mantener el orden de inserción!!

Esperemos que esto conduzca a una implementación de OrderedDict de capa delgada como primer paso. Como @ JimFasarakis-Hilliard indicó, algunos ven casos de uso para el tipo OrderedDict también en el futuro. Creo que la comunidad de Python en general inspeccionará cuidadosamente, si esto resistirá la prueba del tiempo, y cuáles serán los próximos pasos.

Es hora de repensar nuestros hábitos de codificación para no perder las posibilidades abiertas por el ordenamiento estable de:

  • Argumentos de palabras clave y
  • (intermedio) dict storage

La primera porque facilita el envío en la implementación de funciones y métodos en algunos casos.

El en segundo lugar, ya que fomenta el uso más fácil de dicts como almacenamiento intermedio en tuberías de procesamiento.

Raymond Hettinger amablemente proporcionó documentación explicando " La Tecnología Detrás de los Diccionarios Python 3.6 " - de su presentación del Grupo San Francisco Python Meetup 2016-DIC-08.

Y tal vez bastantes páginas de preguntas y respuestas decoradas de alto desbordamiento de pila recibirán variantes de esta información y muchas respuestas de alta calidad requerirán una actualización por versión demasiado.

Caveat Emptor (pero también ver a continuación actualización 2017-12-15):

Como bien señala @ajcr: "El aspecto de preservar el orden de esta nueva implementación se considera un detalle de implementación y no se debe confiar en él."(de la whatsnew36) no nit picking, pero la cita fue cortada un poco pesimista ;-). Continúa como " (esto puede cambiar en el futuro, pero se desea tener esta nueva implementación dict en el lenguaje para algunas versiones antes cambiar la especificación del lenguaje a la semántica de orden de mandato-preservación para todas las implementaciones de Python actuales y futuras; esto también ayuda a preservar la compatibilidad hacia atrás con versiones anteriores del lenguaje donde el orden de iteración aleatoria todavía está en efecto, por ejemplo, Python 3.5)."

Así como en algunos idiomas humanos (por ejemplo, el alemán), el uso moldea el idioma, y el testamento ahora ha sido declarado ... en whatsnew36.

Actualización 2017-12-15:

En un correo al python-dev list , Guido van Rossum declaró:

Hazlo así. "Dict mantiene la orden de inserción" es el fallo. ¡Gracias!

Por lo tanto, el efecto secundario de la versión 3.6 CPython de ordenar la inserción de dict ahora se está convirtiendo en parte de la especificación del lenguaje (y ya no solo un detalle de implementación). Ese hilo de correo también emergió algunos objetivos de diseño distintivos para collections.OrderedDict como lo recordó Raymond Hettinger durante la discusión.

 53
Author: Dilettant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-16 15:47:55

Dado el diccionario

e = {1:39, 4:34, 7:110, 2:87}

Ordenando

sred = sorted(e.items(), key=lambda value: value[1])

Resultado

[(4, 34), (1, 39), (2, 87), (7, 110)]

Puede usar una función lambda para ordenar las cosas por valor y almacenarlas procesadas dentro de una variable, en este caso sred con e el diccionario original.

¡Espero que eso ayude!

 41
Author: Bishop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-30 11:49:21

Tuve el mismo problema, y lo resolví así:

WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

(Personas que contestan "no es posible ordenar un dict" no leer la pregunta! De hecho, " Puedo ordenar en las claves, pero ¿cómo puedo ordenar basado en los valores?"claramente significa que quiere una lista de las claves ordenadas según el valor de sus valores.)

Tenga en cuenta que el orden no está bien definido (las claves con el mismo valor estarán en un orden arbitrario en la lista de salida).

 37
Author: jimifiki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-28 13:44:24

En Python 2.7, simplemente haga:

from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by key
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

Copiar y pegar desde: http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

Disfruta; -)

 31
Author: sweetdream,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-22 08:38:48

Este es el código:

import operator
origin_list = [
    {"name": "foo", "rank": 0, "rofl": 20000},
    {"name": "Silly", "rank": 15, "rofl": 1000},
    {"name": "Baa", "rank": 300, "rofl": 20},
    {"name": "Zoo", "rank": 10, "rofl": 200},
    {"name": "Penguin", "rank": -1, "rofl": 10000}
]
print ">> Original >>"
for foo in origin_list:
    print foo

print "\n>> Rofl sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rofl")):
    print foo

print "\n>> Rank sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rank")):
    print foo

Aquí están los resultados:

Original

{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}

Rofl

{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}

Rango

{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
 23
Author: PedroMorgan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-02 07:42:26

Si los valores son numéricos, también puede usar Contador de colecciones

from collections import Counter

x={'hello':1,'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]    
 22
Author: Ivan Sas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-27 15:49:32

Técnicamente, los diccionarios no son secuencias, y por lo tanto no se pueden ordenar. Puedes hacer algo como

sorted(a_dictionary.values())

Suponiendo que el rendimiento no es un gran problema.

 20
Author: Hank Gay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-28 13:43:47

Puede crear un "índice invertido", también

from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
    inverse[v].append( k )

Ahora su inverso tiene los valores; cada valor tiene una lista de claves aplicables.

for k in sorted(inverse):
    print k, inverse[k]
 18
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-05 01:52:18

Puede usar las colecciones .Contador. Nota, esto funcionará tanto para valores numéricos como no numéricos.

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> from collections import Counter
>>> #To sort in reverse order
>>> Counter(x).most_common()
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> Counter(x).most_common()[::-1]
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
>>> #To get a dictionary sorted by values
>>> from collections import OrderedDict
>>> OrderedDict(Counter(x).most_common()[::-1])
OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])
 18
Author: Abhijit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-03 17:04:58

Intente el siguiente enfoque. Definamos un diccionario llamado mydict con los siguientes datos:

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

Si uno quisiera ordenar el diccionario por claves, uno podría hacer algo como:

for key in sorted(mydict.iterkeys()):
    print "%s: %s" % (key, mydict[key])

Esto debería devolver la siguiente salida:

alan: 2
bob: 1
carl: 40
danny: 3

Por otro lado, si uno quisiera ordenar un diccionario por valor (como se pregunta en la pregunta), uno podría hacer lo siguiente:

for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
    print "%s: %s" % (key, value)

El resultado de este comando (ordenando el diccionario por valor) debe devolver el siguiente:

bob: 1
alan: 2
danny: 3
carl: 40
 18
Author: Nathaniel Payne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-23 23:11:19

Puede usar un skip dict que es un diccionario que está permanentemente ordenado por valor.

>>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> SkipDict(data)
{0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}

Si usa keys(), values() o items() entonces iterarás en orden ordenado por valor.

Se implementa usando la estructura de datos skip list.

 14
Author: malthe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-25 22:56:55

Esto devuelve la lista de pares clave-valor en el diccionario, ordenados por valor de mayor a menor:

sorted(d.items(), key=lambda x: x[1], reverse=True)

Para el diccionario ordenado por clave, use lo siguiente:

sorted(d.items(), reverse=True)

El retorno es una lista de tuplas porque los diccionarios mismos no pueden ser ordenados.

Esto se puede imprimir o enviar a otros cálculos.

 14
Author: Zags,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-09 22:56:19
from django.utils.datastructures import SortedDict

def sortedDictByKey(self,data):
    """Sorted dictionary order by key"""
    sortedDict = SortedDict()
    if data:
        if isinstance(data, dict):
            sortedKey = sorted(data.keys())
            for k in sortedKey:
                sortedDict[k] = data[k]
    return sortedDict
 13
Author: Argun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-01 12:16:41

También puede usar la función personalizada que se puede pasar a key.

def dict_val(x):
    return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)

Una forma más de hacerlo es usar la función labmda

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda t: t[1])
 12
Author: Vishwanath Rawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-25 18:13:11

Aquí hay una solución usando zip on d.values() y d.keys(). Unas pocas líneas más abajo de este enlace (en los objetos de vista de diccionario) es:

Esto permite la creación de pares (valor, clave) usando zip(): pairs = zip(d.values(), d.keys()).

Así que podemos hacer lo siguiente:

d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}

d_sorted = sorted(zip(d.values(), d.keys()))

print d_sorted 
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]
 9
Author: Scott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-20 01:44:58

Use ValueSortedDict de dicts :

from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items() 

[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
 7
Author: ponty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-19 06:25:41

Itera a través de un dict y lo ordena por sus valores en orden descendente:

$ python --version
Python 3.2.2

$ cat sort_dict_by_val_desc.py 
dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5)
for word in sorted(dictionary, key=dictionary.get, reverse=True):
  print(word, dictionary[word])

$ python sort_dict_by_val_desc.py 
aina 5
tuli 4
joka 3
sana 2
siis 1
 6
Author: juhoh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-30 19:42:06

, se me ocurrió este,

import operator    
x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_x = {k[0]:k[1] for k in sorted(x.items(), key=operator.itemgetter(1))}

Para Python 3.x: x.items() reemplazando a iteritems().

>>> sorted_x
{0: 0, 1: 2, 2: 1, 3: 4, 4: 3}

O prueba con collections.OrderedDict!

x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
from collections import OrderedDict

od1 = OrderedDict(sorted(x.items(), key=lambda t: t[1]))
 6
Author: octoback,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-03 17:07:59

Puede utilizar la función ordenada de Python

sorted(iterable[, cmp[, key[, reverse]]])

Así que puedes usar:

sorted(dictionary.items(),key = lambda x :x[1])

Visite este enlace para obtener más información sobre la función ordenada: https://docs.python.org/2/library/functions.html#sorted

 6
Author: kkk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-20 19:54:27

Por supuesto, recuerda, necesitas usar OrderedDict porque los diccionarios regulares de Python no mantienen el orden original.

from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key = lambda x: x[1]))

Si no tiene Python 2.7 o superior, lo mejor que puede hacer es iterar sobre los valores en una función generadora. (Hay un OrderedDict para 2.4 y 2.6 aquí , pero

a) I don't know about how well it works 

Y

b) You have to download and install it of course. If you do not have administrative access, then I'm afraid the option's out.)

def gen(originalDict):
    for x,y in sorted(zip(originalDict.keys(), originalDict.values()), key = lambda z: z[1]):
        yield (x, y)
    #Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want. 

for bleh, meh in gen(myDict):
    if bleh == "foo":
        print(myDict[bleh])

También puede imprimir cada valor

for bleh, meh in gen(myDict):
    print(bleh,meh)

Por favor, recuerde eliminar los paréntesis después de imprimir si no usando Python 3.0 o superior

 6
Author: ytpillai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-31 08:35:05

Como señaló Dilettant, Python 3.6 ahora mantendrá el orden! Pensé en compartir una función que escribí que facilita la ordenación de un iterable (tupla, lista, dict). En este último caso, puede ordenar por claves o valores, y puede tener en cuenta la comparación numérica. Solo para >= 3.6!

Cuando intentas usar sorted en un iterable que contiene, por ejemplo, cadenas, así como ints, sorted() fallará. Por supuesto, puede forzar la comparación de cadenas con str (). Sin embargo, en algunos casos desea hacer comparación numérica real donde 12 es menor que 20 (que no es el caso en la comparación de cadenas). Así que se me ocurrió lo siguiente. Cuando desee una comparación numérica explícita, puede usar la bandera num_as_num que intentará hacer una clasificación numérica explícita al intentar convertir todos los valores en flotadores. Si eso tiene éxito, hará una clasificación numérica, de lo contrario recurrirá a la comparación de cadenas.

Comentarios para mejorar o push solicitudes bienvenidas.

def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
    def _sort(i):
      # sort by 0 = keys, 1 values, None for lists and tuples
      try:
        if num_as_num:
          if i is None:
            _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
          else:
            _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
        else:
          raise TypeError
      except (TypeError, ValueError):
        if i is None:
          _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
        else:
          _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))

      return _sorted

    if isinstance(iterable, list):
      sorted_list = _sort(None)
      return sorted_list
    elif isinstance(iterable, tuple):
      sorted_list = tuple(_sort(None))
      return sorted_list
    elif isinstance(iterable, dict):
      if sort_on == 'keys':
        sorted_dict = _sort(0)
        return sorted_dict
      elif sort_on == 'values':
        sorted_dict = _sort(1)
        return sorted_dict
      elif sort_on is not None:
        raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
    else:
      raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")
 6
Author: Bram Vanroy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-07 11:26:03

Si sus valores son enteros, y usa Python 2.7 o posterior, puede usar collections.Counter en lugar de dict. El método most_common le dará todos los elementos, ordenados por el valor.

 5
Author: Petr Viktorin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-24 19:50:43