¿Cómo ordenar una lista de diccionarios por un valor del diccionario en Python?

4 minutos de lectura

¿Cómo clasifico una lista de diccionarios por el valor de una clave específica? Dado:

[{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]

cuando se ordena por namedebe convertirse en:

[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]

  • Leyendo la respuesta y mirando operador.itemgetter. ¿Puedo ordenar varios valores en el mismo proceso (por ejemplo, tenemos [{'name':'Bart', 'age':10, 'note':3},{'name':'Homer','age':10,'note':2},{'name':'Vasile','age':20,'note':3}] Y para usar: from operator import itemgetter newlist = sorted(old_list, key=itemgetter(-'note','name') EDITAR: Probado y funciona, pero no sé cómo anotar DESC y nombrar ASC.

    – claudio

    21 de mayo de 2020 a las 7:13


Avatar de usuario de Mario F.
mario f

El sorted() función toma un key= parámetro

newlist = sorted(list_to_be_sorted, key=lambda d: d['name']) 

Como alternativa, puede utilizar operator.itemgetter en lugar de definir la función usted mismo

from operator import itemgetter
newlist = sorted(list_to_be_sorted, key=itemgetter('name')) 

Para completar, agregue reverse=True ordenar en orden descendente

newlist = sorted(list_to_be_sorted, key=itemgetter('name'), reverse=True)

  • El uso de la llave no solo es más limpio sino también más eficiente.

    – jfs

    16 de septiembre de 2008 a las 15:03

  • La forma más rápida sería agregar una instrucción newlist.reverse(). De lo contrario, puede definir una comparación como cmp=lambda x,y: – cmp(x[‘name’],y[‘name’]).

    – Mario F.

    13 de octubre de 2009 a las 7:14

  • si el valor de clasificación es un número, podría decir: lambda k: (k[‘age’] * -1) para obtener una ordenación inversa

    – Philluminati

    20 de noviembre de 2009 a las 15:16

  • Esto también se aplica a una lista de tuplas, si usa itemgetter(i) dónde i es el índice del elemento de tupla a ordenar.

    – radicando

    11 de julio de 2012 a las 23:14

  • itemgetter acepta más de un argumento: itemgetter(1,2,3) es una función que devuelve una tupla como obj[1], obj[2], obj[3]por lo que puede usarlo para realizar clasificaciones complejas.

    – Bakuriu

    7 sep 2012 a las 17:59

import operator

Para ordenar la lista de diccionarios por key=’name’:

list_of_dicts.sort(key=operator.itemgetter('name'))

Para ordenar la lista de diccionarios por clave=’edad’:

list_of_dicts.sort(key=operator.itemgetter('age'))

  • De todos modos para combinar el nombre y la edad? (como en SQL ORDEN POR nombre, ¿edad?)

    – monojohnny

    17 de febrero de 2010 a las 13:10


  • @monojohnny: sí, solo haz que la clave devuelva una tupla, key=lambda k: (k['name'], k['age']). (o key=itemgetter('name', 'age')). de tupla cmp comparará cada elemento a su vez. es malditamente brillante.

    – claudio

    04/09/2013 a las 22:21


  • En la documentación (docs.python.org/2/tutorial/datastructures.html) el opcional key argumento a favor list.sort() no se describe. ¿Alguna idea de dónde encontrar eso?

    – TTT

    21 de febrero de 2014 a las 15:21


  • @TTT: Ver el documentación de la biblioteca para list y amigos.

    –Kevin

    19 de febrero de 2015 a las 14:56

avatar de usuario de pjz
pjz

my_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

my_list.sort(lambda x,y : cmp(x['name'], y['name']))

my_list ahora será lo que quieras.

O mejor:

Desde Python 2.4, hay un key argumento es a la vez más eficiente y más ordenado:

my_list = sorted(my_list, key=lambda k: k['name'])

…la lambda es, en mi opinión, más fácil de entender que operator.itemgetterpero tu kilometraje puede variar.

  • ¿Qué se podría hacer si la clave es desconocida y sigue cambiando? Me refiero a una lista de dictados con solo una clave y valor, pero la clave y el valor no se pueden definir ya que siguen cambiando.

    – sam

    1 de diciembre de 2020 a las 14:51

  • Necesitaría más de un ejemplo para mirar. Intente enviar una posible solución en codereview stackexchange y pregunte si hay una mejor manera.

    – pjz

    30 de diciembre de 2020 a las 1:02

  • @Sam si desea ordenar por el valor de la clave única en el dict, incluso si no conoce la clave, puede hacerlo key=lambda k: list(k.values())[0]

    – pjz

    10 de marzo de 2021 a las 6:38

Si desea ordenar la lista por varias claves, puede hacer lo siguiente:

my_list = [{'name':'Homer', 'age':39}, {'name':'Milhouse', 'age':10}, {'name':'Bart', 'age':10} ]
sortedlist = sorted(my_list , key=lambda elem: "%02d %s" % (elem['age'], elem['name']))

Es bastante complicado, ya que se basa en convertir los valores en una representación de cadena única para la comparación, pero funciona como se espera para los números, incluidos los negativos (aunque deberá formatear su cadena de manera adecuada con cero rellenos si está usando números).

a = [{'name':'Homer', 'age':39}, ...]

# This changes the list a
a.sort(key=lambda k : k['name'])

# This returns a new list (a is not modified)
sorted(a, key=lambda k : k['name']) 

avatar de usuario de efotinis
efotinis

import operator
a_list_of_dicts.sort(key=operator.itemgetter('name'))

‘key’ se usa para ordenar por un valor arbitrario y ‘itemgetter’ establece ese valor en el atributo ‘name’ de cada elemento.

Avatar de usuario de Bartosz Radaczyński
Bartosz Radaczyński

Supongo que quisiste decir:

[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

Esto se ordenaría así:

sorted(l,cmp=lambda x,y: cmp(x['name'],y['name']))

¿Ha sido útil esta solución?