简体   繁体   English

Python如何根据对象的属性根据另一个列表对对象列表进行排序

[英]Python how to sort list of objects based on their attribute according to another list

That is a confusing title. 那是一个令人困惑的标题。

Lets say I have a list of IDs 可以说我有一个ID列表

ids = [3, 1, 2, 4]

And I am retrieving the objects in one go, for example in Django: 而且我要一次性检索对象,例如在Django中:

records = Record.objects.filter(id__in=ids)

How do I keep the order of records according to another list, elegantly , preferably using built-in sort functions ? 如何优雅地最好使用内置排序功能)根据另一个列表保持记录的顺序?

The only way I can think of right now is in traditional code with minimum loops, covert the records to dictionary first, then loop through the ids to pick the record in the dictionary directly, see below: 我现在能想到的唯一方法是在具有最小循环的传统代码中,首先将记录隐式转换为字典,然后循环遍历id以直接在字典中选择记录,请参见以下内容:

result = []
dict_of_records = {r.id: r for r in records}
for id in ids:
    result.append(dict_of_records[id])

Use sorted() and specify the sort key with the key keyword arg: 使用sorted()并使用key关键字arg指定排序关键字:

sorted(records, key=lambda x: ids.index(x))

this however will be inefficient , because it will require a lookup ( ids.index(x) ) for each record. 但是这将是低效率的 ,因为它将需要为每个记录进行查找( ids.index(x) )。

It will be more efficient if you precompute the sort key: 如果您预先计算了排序键,它将更加高效:

sortkey = {j:i for i,j in enumerate(ids)}
sorted(records, key=lambda x: sortkey[x])

Personally, I wouldn't use a sort-based solution. 就个人而言,我不会使用基于排序的解决方案。 A sort would take O(Nlog(N)) time for N records, but we can solve the problem in O(N) time. 排序将花费O(Nlog(N))的时间来处理N个记录,但是我们可以解决O(N)的时间的问题。 That said, a sort would look like this: 也就是说,排序看起来像这样:

positions = {j:i for i, j in enumerate(ids)}
result = sorted(Record.objects.filter(id__in=ids), key=lambda r:positions[r.id])

What I would do is use the positions table to put each record in its final position immediately: 我要做的是使用positions表将每个记录立即置于其最终位置:

result = [None]*len(positions)
for record in Record.objects.filter(id__in=ids):
    result[positions[record.id]] = record

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM