¿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 name
debe convertirse en:
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
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óndei
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 comoobj[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'])
. (okey=itemgetter('name', 'age')
). de tuplacmp
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 favorlist.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
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.itemgetter
pero 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'])
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.
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']))
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