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

时间:2019-04-15 14:19:54

标签: python sorting

我的数据由具有某些属性(pk)的对象组成:

obj0.pk = 'aa'
obj1.pk = 33
ojb2.pk = 'm0'

我有一堆无序对象:

data = [obj0, obj1, obj2]

我有pk列表,用于指定如何订购对象:

pks = [33, 'aa', 'm0']

现在我调用一个函数来排序数据:

output = sort_data_by_pk(data, pks)

预期输出:

[obj1, obj0, obj2]

我们如何在python中实现sort_data_by_pk

编辑

我最初的实现是:

def sort_data_by_pk(data, pks):
    lookup = {instance.pk: instance for instance in data}
    return [lookup[pk] for pk in pks]

4 个答案:

答案 0 :(得分:3)

使用index方法作为键函数不必要地使解决方案 O(n ^ 2 log n)而不是 O(n log n)平均时间复杂度。

相反,您可以构建一个将data中的项目映射到其索引的字典,以便可以使用该字典将对象的pk属性映射为排序顺序的关键函数:

order = {k: i for i, k in enumerate(pks)}
output = sorted(data, key=lambda o: order[o.pk])

答案 1 :(得分:2)

您可以根据sort中的data index pks

>>> pks = [33, 'aa', 'm0']
>>> data = [ob0, ob1, ob2]
>>> 
>>> 
>>> sorted(data, key=lambda x: pks.index(x.pk))
[<__main__.Obj object at 0x7f03851cc290>, <__main__.Obj object at 0x7f03851cc250>, <__main__.Obj object at 0x7f03851cc2d0>]

答案 2 :(得分:2)

我认为您想将sorted与一个lambda一起使用,以获取pks中主键的索引。

sorted_data = sorted(data, lambda d: pks.index(d.pk))

答案 3 :(得分:2)

如果列表很大,则可能要先创建一个dict,以避免在列表上多次调用“ index”。

pks = [33, 'aa', 'm0']
data = [ob0, ob1, ob2]
d = { obj.pk: obj for obj in data } #lookup table for pks
sorted_list = [ d[pk] for pk in pks ] #create a new list out of list "pks" where pk is replaced by the value in the lookup table