使用每个对象具有的“ order”属性对对象列表进行重新排序的最有效方法

时间:2019-07-03 15:50:50

标签: python python-2.7 performance python-performance

我正在尝试创建一种算法,该算法将遍历对象列表并对它们进行排序,但是排序不完全像基于属性移动列表项一样,原始列表的顺序不会改变,定义顺序的不是对象在列表中的排序方式,而是每个对象称为order的属性,它是一个整数。

为了使其更加复杂,此重新排序是基于另一个列表(这里称为reorderer_list)进行的,该列表包含表示对象的字典,其所有属性包括order,但它们是只是简单地按正确的顺序在此reorderer_list中排序(它们的order属性也可能不正确)

这种情况的一个基本例子是:

reorderer_list = [{"order": 7, "name": "Tom"}, {"order": 5, "name": "Sara"}, {"order": 6, "name": "John"}]

原始列表(按这三个人的未知顺序排列)最终应该变成

[{"order": 5, "name": "Tom"}, {"order": 6, "name": "Sara"}, {"order": 7, "name": "John"}]

[{"order": 6, "name": "Sara"}, {"order": 7, "name": "John"}, {"order": 5, "name": "Tom"}]

没关系,两者都是正确的(它们都是正确的,因为最终列表中项目的排序无关紧要,重要的是{strong>仅 {只是使用此示例进行了说明。原始列表将包含这三个名称(例如),并且在列表内按order的任意值排序,这无所谓,最后原始列表{ {1}}属性应安排为与其中的项目的reorderer_list实际排序相匹配。

重要的是要注意有时原始列表和重新排序的列表的大小可能不相同,位置改变的对象将始终存在于两个列表中

这是我已经尝试过的: order是原始列表,order是具有正确顺序的新列表

list_data

它可以工作,但是我想知道是否有任何方法可以改善这种混乱状况?

2 个答案:

答案 0 :(得分:0)

那呢?

def change_order_value(items):
    new_orders = [item['order'] for item in sorted(items, key=lambda x: x['order'])]
    for new_order, item in zip(new_orders, items):
        item['order'] = new_order
    return items


reorderer_list = [{"order": 7, "name": "Tom"}, {"order": 5, "name": "Sara"}, {"order": 6, "name": "John"}]
print(change_order_value(reorderer_list))
# [{'order': 5, 'name': 'Tom'}, {'order': 6, 'name': 'Sara'}, {'order': 7, 'name': 'John'}]

答案 1 :(得分:0)

IIUC这是OP想要的:

initial_list = [{"order": 5, "name": "Sara"}, {"order": 6, "name": "John"}, {"order": 7, "name": "Tom"}]

reorderer_list = [{"order": 7, "name": "Tom"}, {"order": 5, "name": "Sara"}, {"order": 6, "name": "John"}]

def answer(initial_list, reorderer_list):
     sorted_order = sorted([e["order"] for e in reorderer_list])
     d = { e["name"]: order
           for e, order in zip(reorderer_list, sorted_order) }
     for e in initial_list: 
         e["order"] = d[e["name"]]