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

时间:2015-06-17 21:00:52

标签: python

这是一个令人困惑的标题。

假设我有一个ID列表

ids = [3, 1, 2, 4]

我正在一次性检索对象,例如在Django中:

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

如何根据另一个列表保留记录顺序,优雅最好使用内置排序功能

我现在能想到的唯一方法是使用最小循环的传统代码,首先将记录转换为字典,然后循环遍历id以直接在字典中选择记录,如下所示:

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

2 个答案:

答案 0 :(得分:2)

使用sorted()并使用key关键字arg:

指定排序键
sorted(records, key=lambda x: ids.index(x))

然而,这将是效率低下,因为它需要为每条记录进行查找(ids.index(x))。

如果预先计算排序键,效率会更高:

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

答案 1 :(得分:0)

就个人而言,我不会使用基于排序的解决方案。对于N个记录,排序将花费O(Nlog(N))时间,但是我们可以在O(N)时间内解决该问题。那就是说,一种看起来像这样:

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

我要做的是使用positions表将每条记录立即置于最终位置:

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