Как более красиво реализовать сортировку списка словарей на основе значений из другого словаря?

Имеется словарь с вложенными словарями и список словарей:

PLATINUM = 10
GOLD = 9

products_by_id = {77: {'type': PLATINUM}, 883: {'type': GOLD}, 9: {'type': PLATINUM}, 714: {'type': GOLD}, 459: {'type': PLATINUM}, 16: {'type': GOLD}, 978: {'type': GOLD}, 403: {'type': GOLD}, 149: {'type': PLATINUM}, 957: {'type': GOLD}, 981: {'type': PLATINUM}}

prices = [{'id': 1, 'product': 149}, {'id': 10, 'product': 9}, {'id': 2, 'product': 957} , {'id': 3, 'product': 77} , {'id': 15, 'product': 983}]

Я хочу отсортировать список prices так, чтобы впереди шли цены, которые привязаны к продуктам с типом GOLD

Я могу это сделать так:

>>> sorted(prices, key=lambda p: products_by_id.get(p['product'], {}).get('type') == GOLD, reverse=True)
[{'product': 957, 'id': 2}, {'product': 149, 'id': 1}, {'product': 9, 'id': 10}, {'product': 77, 'id': 3}, {'product': 983, 'id': 15}]

Что выглядит ужасно, да еще и вызывает два метода get(). Можно ли реализовать подобную сортировку более красивым способом? (Не вынося лямбду в "полноценную" функцию)


Ответы (1 шт):

Автор решения: MiniMax

Для простого перемещения GOLD элементов в начало списка сортировка не нужна, можно просто создать новый список и все GOLD элементы добавлять в его начало, а все остальные в конец. В итоге получите тоже самое, только быстрее: сам алгоритм имеет O(N) сложность + экономите время на вызовах лямбды.

from pprint import pprint

PLATINUM = 10
GOLD = 9 

products_by_id = { 
                    9: {'type': PLATINUM},
                    16: {'type': GOLD},
                    77: {'type': PLATINUM},
                    149: {'type': PLATINUM},
                    403: {'type': GOLD},
                    459: {'type': PLATINUM},
                    714: {'type': GOLD},
                    883: {'type': GOLD},
                    957: {'type': GOLD},
                    978: {'type': GOLD},
                    981: {'type': PLATINUM}
                }
prices = [ 
            {'id': 1, 'product': 149},
            {'id': 10, 'product': 9}, 
            {'id': 2, 'product': 957},
            {'id': 3, 'product': 77},
            {'id': 15, 'product': 983}
        ]

sorted_prices = []
for price in prices:
    if price['product'] in products_by_id and products_by_id[price['product']]['type'] == GOLD:
        sorted_prices.insert(0, price)
    else:
        sorted_prices.append(price)

pprint(sorted_prices)

Output

[{'id': 2, 'product': 957},
 {'id': 1, 'product': 149},
 {'id': 10, 'product': 9},
 {'id': 3, 'product': 77},
 {'id': 15, 'product': 983}]
→ Ссылка