我有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
循环来检查和添加每个元素,但是这样做有什么优雅的方法(或更复杂)吗?
答案 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)))
答案 2 :(得分:2)
使用sorted
函数,您可以指定该函数应在其后排序的键。您要访问每个字典的"uid"
键的值,并且uid_order
中该值的索引确定排序列表中该字典的索引:
sorted(data, key = lambda x: uid_order.index(x["uid"]))
此代码的含义是,列表的每个元素都传递给lambda
函数。结果值用作排序后的键。