按特定键的顺序对字典列表进行排序

时间:2020-03-28 07:44:54

标签: python python-3.x sorting dictionary

我有list的{​​{1}},例如:

dict

现在,我想按data = [{"uid": "a1", "name": "b1"}, {"uid": "a3", "name": "b3"}, {"uid": "a4", "name": "b4"}, {"uid": "a5", "name": "b5"}] 字段的顺序对list进行排序,如下所示:

uid

这意味着输出应为:

uid_order = ['a1', 'a5', 'a3', 'a4']

当然,我可以创建一个新的空[{"uid": "a1", "name": "b1"}, {"uid": "a5", "name": "b5"}, {"uid": "a3", "name": "b3"}, {"uid": "a4", "name": "b4"}] ,然后使用2个list循环来检查和添加每个元素,但是这样做有什么优雅的方法(或更复杂)吗?

3 个答案:

答案 0 :(得分:4)

O(n)解决方案:

>>> [*map({d['uid']: d for d in data}.get, uid_order)]
[{'uid': 'a1', 'name': 'b1'},
 {'uid': 'a5', 'name': 'b5'},
 {'uid': 'a3', 'name': 'b3'},
 {'uid': 'a4', 'name': 'b4'}]

答案 1 :(得分:3)

如果要避免创建新列表,可以使用sort方法对列表进行排序。这将使用具有O(n log n)复杂性的Timsort,比建议的O(n^2)实现要好得多:

uid_order = {k: i for i, k in enumerate(uid_order)}
data.sort(key=uid_order.get)

为了加快对uid_order的查找,我将其转换为词典(之所以转换为字典,是因为列表将索引映射到项目,而您希望将项目索引)。现在,您可以进行O(n)查找,而不是O(1)查找键的每次评估。

仅使用函数调用制作字典的另一种方法:

uid_order = dict(map(reversed, enumerate(uid_order)))

另请参阅:Python Sorting HOW TO

答案 2 :(得分:2)

使用sorted函数,您可以指定该函数应在其后排序的键。您要访问每个字典的"uid"键的值,并且uid_order中该值的索引确定排序列表中该字典的索引:

sorted(data, key = lambda x: uid_order.index(x["uid"]))

此代码的含义是,列表的每个元素都传递给lambda函数。结果值用作排序后的键。