如何按照Python中字典的值对字典列表进行sorting?

我得到了一个字典列表,并希望按字典的值进行sorting。

这个

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

按名称sorting,应该成为

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

它可能看起来更清洁使用一个键,而不是一个cmp:

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

或者像JFSebastian和其他人所build议的那样,

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

为了完整性(正如在fitzgeraldsteele的评论中指出的),添加reverse=True来降序sorting

 newlist = sorted(l, key=itemgetter('name'), reverse=True) 
 import operator 

按键=“名称”对字典列表进行sorting:

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

按键='年龄'对字典列表进行sorting:

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

如果您想按多个键对列表进行sorting,您可以执行以下操作:

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

这是相当黑客的,因为它依赖于将值转换为一个单一的string表示forms进行比较,但它可以按照预期的方式对包括负数的数字进行操作(尽pipe如果您使用的是数字,则需要使用零填充来适当地格式化string)

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

… lambda是IMO,比operator.itemgetter更容易理解,但是YMMV。

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

'key'用于按任意值sorting,'itemgetter'将该值设置为每个项目的'name'属性。

我想你的意思是:

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

这将被sorting如下:

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

使用Perl的Schwartzian转换,

 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 Schwartzian变换

在计算机科学中,Schwartzian变换是一种Perl编程习惯用法,用于提高对项目列表进行sorting的效率。 这个习惯用法适用于基于比较的sorting,当sorting实际上是基于元素的某个属性(关键)的sorting时,其中计算该属性是应该执行最less次数的密集操作。 Schwartzian变换值得注意的是它不使用命名的临时数组。

你必须实现你自己的比较函数,它将用名字键的值来比较字典。 请参阅从PythonInfo Wiki中sortingMini-HOW TO

您可以使用自定义比较函数,也可以传入计算自定义sorting键的函数。 这通常更有效,因为密钥只是每个项目计算一次,而比较函数将被调用更多次。

你可以这样做:

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

我尝试了这样的事情:

 my_list.sort(key=lambda x: x['name']) 

它也适用于整数。

这里是另一个通用的解决scheme – 它通过键和值对字典的元素进行sorting。 它的优点 – 不需要指定键,如果某些字典中某些键丢失,它仍然可以工作。

 def sort_key_func(item): """ helper function used to sort list of dicts :param item: dict :return: sorted list of tuples (k, v) """ pairs = [] for k, v in item.items(): pairs.append((k, v)) return sorted(pairs) sorted(A, key=sort_key_func) 

让我们说一下带有下面元素的字典D. sorting只是在sorting中使用键parameter passing自定义函数如下

 D = {'eggs': 3, 'ham': 1, 'spam': 2} def get_count(tuple): return tuple[1] sorted(D.items(), key = get_count, reverse=True) or sorted(D.items(), key = lambda x: x[1], reverse=True) avoiding get_count function call 

https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions

使用pandas软件包是另一种方法,虽然大规模运行时比其他人提出的更传统的方法慢得多:

 import pandas as pd listOfDicts = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}] df = pd.DataFrame(listOfDicts) df = df.sort_values('name') sorted_listOfDicts = df.T.to_dict().values() 

下面是一个小列表和一个大的(100k +)字典列表的基准值:

 setup_large = "listOfDicts = [];\ [listOfDicts.extend(({'name':'Homer', 'age':39}, {'name':'Bart', 'age':10})) for _ in range(50000)];\ from operator import itemgetter;import pandas as pd;\ df = pd.DataFrame(listOfDicts);" setup_small = "listOfDicts = [];\ listOfDicts.extend(({'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}));\ from operator import itemgetter;import pandas as pd;\ df = pd.DataFrame(listOfDicts);" method1 = "newlist = sorted(listOfDicts, key=lambda k: k['name'])" method2 = "newlist = sorted(listOfDicts, key=itemgetter('name')) " method3 = "df = df.sort_values('name');\ sorted_listOfDicts = df.T.to_dict().values()" import timeit t = timeit.Timer(method1, setup_small) print('Small Method LC: ' + str(t.timeit(100))) t = timeit.Timer(method2, setup_small) print('Small Method LC2: ' + str(t.timeit(100))) t = timeit.Timer(method3, setup_small) print('Small Method Pandas: ' + str(t.timeit(100))) t = timeit.Timer(method1, setup_large) print('Large Method LC: ' + str(t.timeit(100))) t = timeit.Timer(method2, setup_large) print('Large Method LC2: ' + str(t.timeit(100))) t = timeit.Timer(method3, setup_large) print('Large Method Pandas: ' + str(t.timeit(1))) #Small Method LC: 0.000163078308105 #Small Method LC2: 0.000134944915771 #Small Method Pandas: 0.0712950229645 #Large Method LC: 0.0321750640869 #Large Method LC2: 0.0206089019775 #Large Method Pandas: 5.81405615807 
 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']) 

有时我们需要使用lower()作为例子

 lists = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}, {'name':'abby', 'age':9}] lists = sorted(lists, key=lambda k: k['name']) print(lists) # [{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}, {'name':'abby', 'age':9}] lists = sorted(lists, key=lambda k: k['name'].lower()) print(lists) # [ {'name':'abby', 'age':9}, {'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}] 

这是我对多列sorting相关问题的回答 。 它也适用于列数只有一个的退化情况。