Наиболее эффективный способ переупорядочения списка объектов с использованием свойства order, которое есть у каждого объекта

Я пытаюсь создать алгоритм, который будет проходить через список объектов и сортировать их, но не точно сортировать, как перемещение элементов списка на основе свойства, порядок исходного списка не меняется, что определяет порядок не то, как объекты сортируются внутри списка, а свойство, которое вызывал каждый объект 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"}]

не имеет значения, оба являются правильными (они оба являются правильными, потому что сортировка элементов внутри окончательного списка не имеет значения, значение имеет только order свойство, я просто использовал этот пример, чтобы объяснить это. Исходный список будет содержать эти три имени (например), отсортированные в любом порядке внутри списка с любым значением для orderНеважно, в конце концов, оригинальный список order свойство должно быть организовано так, чтобы оно совпадало с фактической сортировкой reorderer_list элементов внутри него.

Также важно заметить, что иногда исходный список и переупорядоченный список могут иметь разный размер, объекты, у которых изменилась позиция, всегда будут существовать в обоих списках.

Вот что я уже пробовал:list_data это оригинальный список и reorderer_list это новый список с правильным порядком

# This will find the differences between the reordered list and the original list
changedOrderItems = []
changedOrderItemsOrders = []
for index, product in enumerate(list_data):
    #Sizes may be different, avoid IndexError
    if index == len(reorderer_list):
        break
    # Is different
    if product.name != reorderer_list[index]["name"]:
        #Append to temporary list, the items from reorderer list
        changedOrderItems.append(reorderer_list[index])
        #Append to temporary list, the order property of these items
        changedOrderItemsOrders.append(reorderer_list[index]["order"])

#Sort the orders list
changedOrderItemsOrders.sort()

# Cycles through the temporary list and finds the index of the respective object in the original list and sets it's order number according to the sorted changedOrderItemsOrders list
for i, item in enumerate(changedOrderItems):
    from_data_index = next((index for (index, d) in enumerate(list_data) if d.name == item["name"]), None)

    list_data[from_data_index].order = changedOrderItemsOrders[i]

Это работает, но я хочу знать, есть ли способы улучшить этот беспорядок?

2 ответа

Как насчет этого?

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'}]

IIUC это то, что хочет ОП:

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"]] 
Другие вопросы по тегам