使用自定义排序函数按键对字典列表进行排序

3

我有一个字典列表,想要在Python中按照“id”键进行排序。

items = [{'id' : 883},{'id' : 547},{'id' : 898},{'id' : 30},{'id' : 883}]

我希望你能够根据给定的排序顺序将它们按特定顺序排序:
[30, 883, 547, 898]

我该如何在Python3中实现这个功能?


1
这个例子中的排序逻辑是什么? - janos
1
什么逻辑可能导致这种排序?(30 883 547 898) 因为它们忽略了你奇怪而未解释的期望顺序,所以没有一个答案试图回答这个问题,正如@janos所指出的那样。编辑:Brendan的确尊重您要求的顺序。 - Max von Hippel
1
显然,这是一个之字形排序的例子。(开玩笑的,我想) - pault
2个回答

8
使用key参数和一个用于自定义排序顺序的列表。
sort_order = [30, 883, 547, 898]
items.sort(key=lambda d: sort_order.index(d['id']))

根据@Sphinx的建议,您可以事先对列表进行索引以提高速度,复杂度从O(n)变为O(1)

sort_order_index = {val: i for i, val in enumerate(sort_order)}
items.sort(key=lambda d: sort_order_index.get(d['id'], 0))

哦,这就是他想要的吗?很棒的Python技巧,加一分。 - Christian Dean
2
使用sort_order={}而不是sort_order=[]更好吗?sort_order.index(id)应该比dict[id]慢。 - Sphinx
我不太喜欢使用 index,因为它具有 O(n) 的特性。 - Jean-François Fabre
2
@Sphinx:用集合替换列表会破坏sort_order中项目的初始顺序,因此算法会失败。请注意print([30, 883, 547, 898])print({30, 883, 547, 898})之间的区别。 - sciroccorics
@Sphinx 好主意 - Brendan Abel
将代码修改为 sort_order_index.get(d['id'],0),这样不在 sort_order 列表中的项目就不会与 None 进行比较,从而避免了比较器崩溃。 - Jean-François Fabre

0

你可以尝试在一行中不使用循环,像这样:

items = [{'id' : 883},{'id' : 547},{'id' : 898},{'id' : 30},{'id' : 883}]

sorting_order=[30, 883, 547, 898]

print(sorted(items,key=lambda x:sorting_order.index(x['id'])))

输出:

[{'id': 30}, {'id': 883}, {'id': 883}, {'id': 547}, {'id': 898}]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接