Python - 按对象属性对列表进行排序,按第二个列表提供的顺序...可以改进吗?

我有一个不可变对象列表,我需要使用属性作为键对其进行排序。


对象需要按预先指定的顺序排列,而不是简单的升序/降序。


我已经编写了一些可以做到这一点的代码,但我不太相信它会在大列表中表现良好(其中“大”完全是任意的)。今天的用例只是小列表(12 项或更少),但我已经活了足够长的时间,可以期待最终会出现一个大列表。


是否有不同的方法、库或快捷方式我可以利用以使其成为更有效的操作?


# setup

class Demo(object):

    def __init__(self, pk):

        self.pk = pk


    def __repr__(self):

        return f'<Demo: {self.pk}>'


# instantiating objects for the sake of demonstration; actual input I'm given is random!

objects = [Demo(x) for x in range(10)]

# output object should be sorted by pk attribute, with values in this order

ordinality = [9, 0, 8, 4, 5, 1, 3, 7, 6, 2]


# operation in question

result = (next(obj for obj in objects if obj.pk == ordinal) for ordinal in ordinality)


print(tuple(result))

>>> (<Demo: 9>, <Demo: 0>, <Demo: 8>, <Demo: 4>, <Demo: 5>, <Demo: 1>, <Demo: 3>, <Demo: 7>, <Demo: 6>, <Demo: 2>)


蝴蝶不菲
浏览 108回答 3
3回答

慕雪6442864

假设“pk”代表“主键”(唯一),那么您可以只使用 dict(具有O(1)成员资格)而不是使用此类对象的列表(具有O(n)成员资格)objects = [Demo(x) for x in range(10)]&nbsp; # O(n) spaceresult = [next(obj for obj in objects if obj.pk == ordinal] for ordinal in ordinality)&nbsp; # O(n^2) timeobjects = {x: Demo(x) for x in range(10)}&nbsp; # O(n) spaceresult = [objects[pk] for pk in ordinal]&nbsp; # O(n) time

神不在的星期二

首先建立一个查找表,然后使用它。把你的 O(n 2 ) 变成 O(n)。lookup = {obj.pk: obj for obj in objects}result = [lookup[ordinal] for ordinal in ordinality)

犯罪嫌疑人X

您可以只使用序数来创建对象。因为序数是你想要开始的顺序。ordinality = [9, 0, 8, 4, 5, 1, 3, 7, 6, 2]objects = list(map(Demo, ordinality))#orobjects = [Demo(pk) for pk in ordinality]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python