¿Cómo clasifico 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 de cadena es único, por lo que es la clave del diccionario.

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

Nota: he leído la pregunta de desbordamiento de pila aquí ¿Cómo clasifico una lista de diccionarios por un valor del diccionario? y probablemente podría cambiar mi código para tener una lista de diccionarios, pero como realmente no necesito una lista de diccionarios, quería saber si hay una solución más simple para ordenar en orden ascendente o descendente.

preguntado el 04 de marzo de 09 a las 22:03

La estructura de datos del diccionario no tiene un orden inherente. Puede iterar a través de él, pero no hay nada que garantice que la iteración seguirá un orden en particular. Esto es por diseño, por lo que su mejor opción es probablemente utilizar otra estructura de datos para la representación. -

"sorted ()" puede operar en diccionarios (y devuelve una lista de claves ordenadas), así que creo que es consciente de esto. Sin conocer su programa, es absurdo decirle a alguien que está usando la estructura de datos incorrecta. Si las búsquedas rápidas son lo que necesita el 90% del tiempo, probablemente lo que desee sea un dict. -

Los tres resultados (claves, valores, ambos) para ordenar diccionarios se tratan aquí en un estilo claro y conciso: stackoverflow.com/questions/16772071/sort-dict-by-value-python -

@Daishiman Es posible que la clase base no esté ordenada, pero Pedido ordenado es por supuesto. -

En Python 3.6+, los diccionarios conservan el orden de inserción. Esto, por supuesto, no es lo mismo que la posibilidad de ordenarlos por valor, pero por otro lado ya no es válido decir que "la estructura de datos del diccionario no tiene un orden inherente". -

30 Respuestas

Python 3.7+ o CPython 3.6

Los dicts conservan el orden de inserción en Python 3.7+. Lo mismo en CPython 3.6, pero es un detalle de implementación.

>>> x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> {k: v for k, v in sorted(x.items(), key=lambda item: item[1])}
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

or

>>> dict(sorted(x.items(), key=lambda item: item[1]))
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

Python más antiguo

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 ordenados 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 por claves 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 desde no se permite desembalar nosotros podemos usar

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

Si desea la salida como un dictado, puede usar collections.OrderedDict:

import collections

sorted_dict = collections.OrderedDict(sorted_x)

respondido 22 nov., 20:19

para los tiempos en varios diccionarios ordenados por esquemas de valor: escribirsolo.wordpress.com/2008/08/30/… - gregg lind

sorted_x.reverse() le dará un orden descendente (por el segundo elemento de tupla) - dijoimu apale

saidimu: Como ya estamos usando sorted(), es mucho más eficiente pasar el reverse=True argumento. - rmh

En python3 utilicé una lambda: sorted(d.items(), key=lambda x: x[1]). ¿Funcionará esto en Python 2.x? - clave

OrderedDict agregado a las colecciones en 2.7. Ejemplo de clasificación mostrado en: docs.python.org/library/… - monje

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

Bueno, en realidad es posible "ordenar por valores de diccionario". Recientemente tuve que hacer eso en un Code Golf (pregunta de desbordamiento de pila Code golf: tabla de frecuencia de palabras). Resumido, el problema era del tipo: dado un texto, cuente la frecuencia con la que se encuentra cada palabra y muestre una lista de las palabras principales, ordenadas por frecuencia decreciente.

Si construye 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) - la clasificación itera sobre las claves del diccionario, utilizando el número de apariciones de palabras como clave de clasificación.

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 suele decir con "Puedo ordenar fácilmente un diccionario por clave, pero ¿cómo lo ordeno por valor", y creo que la publicación original estaba tratando de abordar ese problema. Y la solución es hacer una especie de lista de claves, basada en los valores, como se muestra arriba.

respondido 10 mar '20, 14:03

Esto también es bueno pero key=operator.itemgetter(1) debe ser más escalable para la eficiencia que key=d.get - smci

@bli sorted_keys = sorted(d.items(), key=itemgetter(1), reverse=True) y for key, val in sorted_keys: print "%s: %d" % (key, val) - itemgetter crea una función cuando se llama, no la usas directamente como en tu ejemplo. Y una iteración simple en un dictado usa las claves sin los valores - Izkatá

Vengo del futuro para contarte collections.Counter, que tiene un most_common método que te puede interesar :) - eevee

Se podría utilizar:

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.

Para ordenarlo en orden descendente, simplemente agregue reverse=True:

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

Entrada:

d = {'one':1,'three':3,'five':5,'two':2,'four':4}
a = sorted(d.items(), key=lambda x: x[1])    
print(a)

Salida:

[('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]

Respondido el 10 de enero de 20 a las 09:01

Por lo que he vistodocs.python.org/2/library/…), hay una clase llamada OrderedDict que se puede ordenar y mantener el orden sin dejar de ser un diccionario. De los ejemplos de código, puede usar lambda para ordenarlo, pero no lo he probado personalmente: P - Nosotros y Rufus

preferiría key=lambda (k, v): v personalmente - Claudiu

@Keyo no debería ser devuelve una lista ordenada de claves (ordenadas por valores) no (k,v) tuplas? Eso es lo que obtengo con Python 2.7.10. @Nyxynyx agregue el parámetro reverse = True para ordenar en orden descendente. - dhj

@Claudiu me gusta eso (k, v) sintaxis también, pero no está disponible en Python 3 donde desembalaje de parámetros de tupla fue removido. - bob stein

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

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

Respondido el 16 de Septiembre de 14 a las 18:09

¿En qué orden están colocadas las llaves con el mismo valor? Primero ordené la lista por claves, luego por valores, pero el orden de las claves con el mismo valor no permanece. - SabreWolfy

Los dictados ahora se pueden ordenar, comenzando con CPython 3.6 y todas las demás implementaciones de Python comenzando con 3.7 - Boris

En Python 2.7 reciente, tenemos el nuevo Pedido ordenado type, 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 crear un nuevo diccionario ordenado a partir del original, ordenando por valores:

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

El OrderedDict se comporta como un dictado 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)])

Respondido 03 Abr '14, 17:04

No se trata de esto, no se trata de mantener el orden de las claves, sino de "ordenar por valor". Nas Banov

@Nas Banov: NO está ordenando por clave. está clasificando en el orden, creamos los elementos. en nuestro caso, ordenamos por valor. Desafortunadamente, el dict de 3 elementos fue elegido, por lo que el orden fue el mismo, cuando se clasificaron por valor y clave, así que amplié el dict de muestra. - mykhal

sorted(d.items(), key=lambda x: x[1]) ¿Puedes explicar qué x significa, por qué puede tomar x[1] a lambda? ¿Por qué no puede ser? x[0]? ¡Muchas gracias! - JZAU

@Boern d.items() devuelve un contenedor similar a una lista de (key, value) tuplas. [0] accede al primer elemento de la tupla, la clave, y [1] accede al segundo elemento: el valor. - Bolígrafo Ben

Nota: A partir de 3.6 (como detalle de implementación de CPython / PyPy) y a partir de 3.7 (como garantía del lenguaje Python), sin formato dict también se ordena la inserción, por lo que puede reemplazar OrderedDict con dict para el código que se ejecuta en Python moderno. OrderedDict ya no es realmente necesario a menos que necesite reorganizar el orden de un existente dict (con move_to_end/popitem) o necesitan que las comparaciones de igualdad sean sensibles al orden. Utiliza mucha más memoria que simple dict, así que si puedes, dict es el camino a seguir. - ShadowRanger

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

Si bien encontré útil la respuesta aceptada, también me sorprendió que no se haya actualizado para hacer referencia Pedido ordenado de la biblioteca estándar colecciones módulo como una alternativa viable y moderna, diseñada 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 Pedido ordenado La documentación también ofrece un ejemplo muy similar, pero usando una lambda para la función de clasificació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)])

Respondido el 15 de diciembre de 15 a las 05:12

Más o menos lo mismo que La respuesta de Hank Gay:

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

O optimizado ligeramente como lo sugiere John Fouhy:

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

respondido 12 mar '19, 05:03

... y al igual que con la respuesta de Hank Gay, no necesita los corchetes. sorted () felizmente tomará cualquier iterable, como una expresión generadora. - Juan Fouhy

Es posible que aún deba intercambiar los elementos de la tupla (valor, clave) para terminar con la (clave, valor). Entonces se necesita otra comprensión de la lista. [(key, value) for (value, key) in sorted_list_of_tuples] - dijoimu apale

no, es mejor dejar corchetes, porque sorted tendrá que reconstruir la lista de todos modos, y la reconstrucción desde gencomp será más rápida. Bueno para el codegolf, malo para la velocidad. Mantener lo feo ([]) versión. - Jean-François Fabre ♦

A menudo puede ser muy útil de usar. tupla nombrada. Por ejemplo, tiene un diccionario de 'nombre' como claves y 'puntuación' como valores y desea ordenar por 'puntuación':

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

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

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

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

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

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

player = best[1]
player.name
    'Richard'
player.score
    7

Respondido 24 Abr '17, 03:04

¿Cómo podría volver a convertirlo en un diccionario? - Rowana

as_list = [Player (v, k) for (k, v) in d.items ()] as_dict = dict ((p.name, p.score) for p in as_list) - Remi

A partir del 3.6 Python se ordenará el dictado incorporado

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

Si dice 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 longitud por supuesto), entonces:

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

Permitir generar más tarde como:

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

ceder 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 actualmente produce:

bar 1
foo 0
baz 42

Detalles:

Según lo propuesto en 2012 por Raymond Hettinger (cf. mail en python-dev con asunto "Diccionarios más compactos con iteración más rápida") y ahora (en 2016) anunciado en un correo de Victor Stinner a python-dev con el asunto "El diccionario de Python 3.6 se vuelve compacto y obtiene una versión privada; y las palabras clave se ordenan" debido a la corrección / implementación del problema 27350 "Dict compacto y ordenado" en Python 3.6 ahora podremos usar un dictado incorporado para mantener el orden de inserción.

Con suerte, esto conducirá a una implementación de OrderedDict de capa delgada como primer paso. Como indicó @ JimFasarakis-Hilliard, 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 que abre el ordenamiento estable de:

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

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

El segundo ya que anima a usar más fácilmente dicts como almacenamiento intermedio en tuberías de procesamiento.

Raymond Hettinger brindó amablemente documentación que explica "La tecnología detrás de los diccionarios de Python 3.6"- de su presentación de San Francisco Python Meetup Group 2016-DIC-08.

Y tal vez algunas páginas de preguntas y respuestas altamente decoradas de Stack Overflow recibirán variantes de esta información y muchas respuestas de alta calidad también requerirán una actualización por versión.

Caveat Emptor (pero también consulte la siguiente actualización 2017-12-15):

Como @ajcr señala con razón: "El aspecto de preservación del orden de esta nueva implementación se considera un detalle de implementación y no se debe confiar en él". (desde el lo nuevo36) no recoger liendres, 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 de dict en el lenguaje para algunas versiones antes de cambiar la especificación del lenguaje para exigir la semántica de preservación del orden para todas las implementaciones actuales y futuras de Python; esto también ayuda a preservar la compatibilidad con versiones anteriores del lenguaje donde el orden de iteración aleatorio todavía está vigente, por ejemplo, Python 3.5) ".

Entonces, como en algunos lenguajes humanos (por ejemplo, alemán), el uso da forma al lenguaje, y la voluntad ahora ha sido declarada ... en lo nuevo36.

Actualizar 2017-12 15-:

En una correo a la lista python-dev, Guido van Rossum declaró:

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

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

Respondido el 16 de diciembre de 17 a las 15:12

Se debe enfatizar la advertencia en la página 'whatsnew' a la que ha vinculado: El aspecto de conservación del orden de esta nueva implementación se considera un detalle de implementación y no se debe confiar en. Nadie debería asumir que el dict type respetará el orden de inserción en su código. Esto no es parte de la definición del lenguaje y la implementación podría cambiar en cualquier versión futura. Continuar usando OrderedDict para garantizar el orden. - Alex Riley

@ajcr gracias por la advertencia, muy apreciado - ya que los emoticonos y los quizás fueron entretejidos en mi respuesta, estos deberían indicar, el cambio es masivo pero por supuesto, solo disponible para CPython (implementación de referencia) y PyPy. Para algo completamente diferente ... Rara vez hablo de detalles de no implementación al codificar instrucciones hombre-máquina. Si solo hubiera sido Jython ;-) ... Puede que no hubiera tenido el coraje de escribirlo. - Diletante

OrderedDict definitivamente no se dejará caer; en su lugar, se convertirá en una envoltura delgada alrededor de la implementación de dict actual (por lo que podría agregar que también se volverá más compacto). Añadiendo ese fragmento con el ImportError no es la mejor idea porque confunde a los lectores que OrderedDict no tiene ningún uso. - Dimitris Fasarakis Hilliard

@ JimFasarakis-Hilliard gracias por los comentarios. "Las mejores ideas" me hicieron sonreír; el futuro a menudo es difícil de predecir. Pero me gusta que su sugerencia verifique las fuentes, lo intente y luego actualice la respuesta en consecuencia. Gracias de nuevo. - Diletante

@AlexRiley Esta advertencia ya no es precisa. Python3.7 garantiza diccionarios ordenados. - Gerrit

Tuve el mismo problema y lo resolví así:

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

(Las personas que respondieron "No es posible ordenar un dictado" no leyeron la pregunta. De hecho, "Puedo ordenar las claves, pero ¿cómo puedo ordenar según los valores?" Significa claramente 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).

respondido 28 nov., 17:13

Falta el valor del resultado: Dejell

Tenga en cuenta que está iterando el diccionario y obteniendo valores por su clave, por lo que en cuanto al rendimiento, esta no es una solución óptima. - ron klein

@Dejell: como dice el colaborador, interpreta la pregunta como "¿Puedo ordenar la lista de claves según los valores?". No necesitamos los valores en el resultado, los tenemos en el diccionario. - Max

Si los valores son numéricos, también puede usar Counter en 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)]    

contestado el 17 de mayo de 19 a las 14:05

¿qué pasa si su diccionario es >>> x = {'hola': 1, 'python': 5, 'mundo': 300} - James

@yopy Counter({'hello':1, 'python':5, 'world':300}).most_common() da [('world', 300), ('python', 5), ('hello', 1)]. Esto realmente funciona para cualquier tipo de valor ordenable (aunque muchos otros Las operaciones de contador requieren que los valores sean comparables a los ints). - lvc

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

Disfrutar ;-)

Respondido 22 ago 13, 09:08

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}

respondido 02 mar '16, 07:03

Pruebe 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, podría hacer algo como:

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

Esto debería devolver el siguiente resultado:

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), 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 (ordenar el diccionario por valor) debería devolver lo siguiente:

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

contestado el 24 de mayo de 18 a las 00:05

¡Impresionante! for key, value in sorted(mydict.iteritems(), key=lambda (k,v): v["score"]): le permite ordenar por una subclave - Andomar

A partir de Python 3.6, dict los objetos ahora están ordenados por orden de inserción. Está oficialmente en las especificaciones de Python 3.7.

>>> words = {"python": 2, "blah": 4, "alice": 3}
>>> dict(sorted(words.items(), key=lambda x: x[1]))
{'python': 2, 'alice': 3, 'blah': 4}

Antes de eso, tenías que usar OrderedDict.

Documentación de Python 3.7 dice:

Modificado en la versión 3.7: Se garantiza que el orden del diccionario será el orden de inserción. Este comportamiento fue un detalle de implementación de CPython desde 3.6.

Respondido 24 Oct 18, 15:10

¡Funciona genial! dict(sorted(words.items(), key=lambda x: x[1], reverse=True)) para DESC - vizyourdata

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 tu inverso tiene los valores; cada valor tiene una lista de claves aplicables.

for k in sorted(inverse):
    print k, inverse[k]

respondido 05 mar '09, 01:03

Puede utilizar el colecciones.. Tenga en cuenta que esto funcionará tanto para valores numéricos como para valores 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)])

Respondido 03 Abr '14, 18:04

¿En qué se diferencia esto de La respuesta de Ivan Sas? - Pedro Mortensen

Puedes utilizar una saltar dictado 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 utiliza keys(), values() or items() luego iterará en orden ordenado por valor.

Se implementa usando el lista de saltos estructura de datos.

Respondido el 25 de Septiembre de 14 a las 23:09

¿Podemos cambiar el orden de clasificación? Ahora mismo, se está enviando, pero yo quiero rechazarlo. - suleman elahi

afaik, tendría que negar sus valores para revertir el orden - malta

También puede utilizar una función personalizada que se puede pasar a la clave.

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)

contestado el 17 de mayo de 19 a las 15:05

Esta es la única respuesta que funcionó hasta ahora en Python 2.7 - rkochev

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

respondido 01 nov., 10:12

La pregunta era: ordenar por valor, no por claves ... Me gusta ver una función. Puede importar colecciones y, por supuesto, usar sorted (data.values ​​()) - Remi

Por supuesto, recuerde, debe usar OrderedDict porque los diccionarios de Python normales 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) No sé qué tan bien funciona

y

b) Tienes que descargarlo e instalarlo por supuesto. Si no tiene acceso administrativo, me temo que la opción está descartada).


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 todos los valores

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

Recuerde eliminar los paréntesis después de imprimir si no usa Python 3.0 o superior

contestado el 17 de mayo de 19 a las 17:05

los diccionarios de Python normales no mantienen el orden original - a partir de Python 3.7, lo hacen. - Gerrit

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

Cuando intente usar sorted en un iterable que contenga, por ejemplo, cadenas e ints, sorted () fallará. Por supuesto, puede forzar la comparación de cadenas con str (). Sin embargo, en algunos casos desea hacer real comparación numérica donde 12 es más pequeño que 20 (que no es el caso en la comparación de cadenas). Entonces 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 tratando de convertir todos los valores en flotantes. Si tiene éxito, hará una clasificación numérica; de lo contrario, recurrirá a la comparación de cadenas.

Comentarios para mejorar bienvenidos.

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

Respondido 19 Feb 21, 09:02

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

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

Entonces 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')]

Respondido el 20 de junio de 15 a las 02:06

Utiliza la ValueSortedDict en dicta:

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

Respondido 19 Oct 11, 07:10

Repita un dict y ordénelo 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

Respondido 30 Oct 11, 19:10

Esto funciona en 3.1.x:

import operator
slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
print(slovar_sorted)

respondido 06 nov., 12:19

En aras de la integridad, estoy publicando una solución usando heapq. Tenga en cuenta que este método funcionará para valores numéricos y no numéricos

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> x_items = x.items()
>>> heapq.heapify(x_items)
>>> #To sort in reverse order
>>> heapq.nlargest(len(x_items),x_items, operator.itemgetter(1))
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> heapq.nsmallest(len(x_items),x_items, operator.itemgetter(1))
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

respondido 23 mar '13, 14:03

Acabo de aprender una habilidad relevante de Python para todos.

Puede utilizar una lista temporal para ayudarle a ordenar el diccionario:

#Assume dictionary to be:
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}

# create a temporary list
tmp = []

# iterate through the dictionary and append each tuple into the temporary list 
for key, value in d.items():
    tmptuple = (value, key)
    tmp.append(tmptuple)

# sort the list in ascending order
tmp = sorted(tmp)

print (tmp)

Si desea ordenar la lista en orden descendente, simplemente cambie la línea de clasificación original a:

tmp = sorted(tmp, reverse=True)

Utilizando la comprensión de listas, la única línea sería:

#Assuming the dictionary looks like
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
#One liner for sorting in ascending order
print (sorted([(v, k) for k, v in d.items()]))
#One liner for sorting in descending order
print (sorted([(v, k) for k, v in d.items()], reverse=True))

Muestra de salida:

#Asending order
[(1.0, 'orange'), (500.1, 'apple'), (789.0, 'pineapple'), (1500.2, 'banana')]
#Descending order
[(1500.2, 'banana'), (789.0, 'pineapple'), (500.1, 'apple'), (1.0, 'orange')]

contestado el 27 de mayo de 18 a las 18:05

esto es ordenar por claves, no por valores. - Rubel

Si desea imprimirlo en el formato inicial, debe hacer: print ([(k, v) para v, k en sorted ([(v, k) para k, v en d.items ()])]). La salida es: [('naranja', 1.0), ('manzana', 500.1), ('piña', 789.0), ('banana', 1500.2)]. Con [(k, v) para v, k en ordenados ([(v, k) para k, v en d.items ()], reverse = True)] la salida es: [('banana', 1500.2), ('piña', 789.0), ('manzana', 500.1), ('naranja', 1.0)] - hermes morales

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

Respondido el 24 de enero de 12 a las 19:01

months = {"January": 31, "February": 28, "March": 31, "April": 30, "May": 31,
          "June": 30, "July": 31, "August": 31, "September": 30, "October": 31,
          "November": 30, "December": 31}

def mykey(t):
    """ Customize your sorting logic using this function.  The parameter to
    this function is a tuple.  Comment/uncomment the return statements to test
    different logics.
    """
    return t[1]              # sort by number of days in the month
    #return t[1], t[0]       # sort by number of days, then by month name
    #return len(t[0])        # sort by length of month name
    #return t[0][-1]         # sort by last character of month name


# Since a dictionary can't be sorted by value, what you can do is to convert
# it into a list of tuples with tuple length 2.
# You can then do custom sorts by passing your own function to sorted().
months_as_list = sorted(months.items(), key=mykey, reverse=False)

for month in months_as_list:
    print month

Respondido 13 Feb 14, 23:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.