为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

蝴蝶不菲 2022-07-19 20:47:29
我有一个不可变对象列表,我需要使用属性作为键对其进行排序。对象需要按预先指定的顺序排列,而不是简单的升序/降序。我已经编写了一些可以做到这一点的代码,但我不太相信它会在大列表中表现良好(其中“大”完全是任意的)。今天的用例只是小列表(12 项或更少),但我已经活了足够长的时间,可以期待最终会出现一个大列表。是否有不同的方法、库或快捷方式我可以利用以使其成为更有效的操作?# setupclass 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 orderordinality = [9, 0, 8, 4, 5, 1, 3, 7, 6, 2]# operation in questionresult = (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>)
查看完整描述

3 回答

?
慕雪6442864

TA贡献1812条经验 获得超5个赞

假设“pk”代表“主键”(唯一),那么您可以只使用 dict(具有O(1)成员资格)而不是使用此类对象的列表(具有O(n)成员资格)


objects = [Demo(x) for x in range(10)]  # O(n) space

result = [next(obj for obj in objects if obj.pk == ordinal] for ordinal in ordinality)  # O(n^2) time


objects = {x: Demo(x) for x in range(10)}  # O(n) space

result = [objects[pk] for pk in ordinal]  # O(n) time


查看完整回答
反对 回复 2022-07-19
?
神不在的星期二

TA贡献1963条经验 获得超6个赞

首先建立一个查找表,然后使用它。把你的 O(n 2 ) 变成 O(n)。


lookup = {obj.pk: obj for obj in objects}

result = [lookup[ordinal] for ordinal in ordinality)


查看完整回答
反对 回复 2022-07-19
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

您可以只使用序数来创建对象。因为序数是你想要开始的顺序。


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


objects = list(map(Demo, ordinality))

#or

objects = [Demo(pk) for pk in ordinality]


查看完整回答
反对 回复 2022-07-19
  • 3 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信