Как отсортировать список словарей по значению словаря? - PullRequest
1610 голосов
/ 16 сентября 2008

У меня есть список словарей, и я хочу, чтобы каждый элемент сортировался по значениям определенного свойства.

Примите во внимание массив ниже,

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

Когда отсортировано по name, должно стать

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

Ответы [ 19 ]

2133 голосов
/ 16 сентября 2008

Может выглядеть чище, если вместо ключа использовать ключ:

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

или, как предположили Дж. Ф. Себастьян и другие,

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

Для полноты (как указано в комментариях fitzgeraldsteele), добавьте reverse=True для сортировки по убыванию

newlist = sorted(l, key=itemgetter('name'), reverse=True)
128 голосов
/ 16 сентября 2008
import operator

Сортировка списка словарей по ключу = 'name':

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

Сортировка списка словарей по ключу = 'age':

list_of_dicts.sort(key=operator.itemgetter('age'))
44 голосов
/ 18 мая 2010

Если вы хотите отсортировать список по нескольким клавишам, вы можете сделать следующее:

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

Это довольно хакерский, поскольку он полагается на преобразование значений в единственное строковое представление для сравнения, но он работает, как и ожидалось, для чисел, в том числе и отрицательных (хотя вам нужно будет соответствующим образом отформатировать строку с нулевыми дополнениями, если вы используете цифры)

42 голосов
/ 16 сентября 2008
my_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

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

my_list теперь будет тем, что вы хотите.

(3 года спустя) Отредактировано, чтобы добавить:

Новый аргумент key более эффективен и аккуратен. Лучший ответ теперь выглядит так:

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

... лямбда, IMO, легче понять, чем operator.itemgetter, но YMMV.

26 голосов
/ 16 сентября 2008
import operator
a_list_of_dicts.sort(key=operator.itemgetter('name'))

«ключ» используется для сортировки по произвольному значению, а «itemgetter» устанавливает это значение для атрибута «name» каждого элемента.

20 голосов
/ 17 марта 2017
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']) 
18 голосов
/ 16 сентября 2008

Полагаю, вы имели в виду:

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

Это будет отсортировано так:

sorted(l,cmp=lambda x,y: cmp(x['name'],y['name']))
17 голосов
/ 27 мая 2013

Используя преобразование Шварца из Perl,

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

сделать

sort_on = "name"
decorated = [(dict_[sort_on], dict_) for dict_ in py]
decorated.sort()
result = [dict_ for (key, dict_) in decorated]

дает

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

Подробнее о Преобразование Перла Шварцяна

В информатике преобразование Шварца - это программирование на Perl идиома используется для повышения эффективности сортировки списка предметов. это идиома подходит для сортировки на основе сравнения, когда порядок на основе порядка определенного свойства (ключа) элементы, где вычисление этого свойства является интенсивной операцией, которая должно быть выполнено минимальное количество раз. Шварцский Transform отличается тем, что не использует именованные временные массивы.

16 голосов
/ 16 сентября 2008

Вы можете использовать пользовательскую функцию сравнения или передать функцию, которая вычисляет пользовательский ключ сортировки. Это обычно более эффективно, поскольку ключ рассчитывается только один раз для каждого элемента, тогда как функция сравнения будет вызываться много раз.

Вы могли бы сделать это так:

def mykey(adict): return adict['name']
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=mykey)

Но стандартная библиотека содержит стандартную процедуру для получения элементов произвольных объектов: itemgetter. Попробуйте вместо этого:

from operator import itemgetter
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=itemgetter('name'))
15 голосов
/ 16 сентября 2008

Вы должны реализовать собственную функцию сравнения, которая будет сравнивать словари по значениям именных ключей. См. Сортировка Mini-HOW TO из PythonInfo Wiki

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...