Как более красиво реализовать сортировку списка словарей на основе значений из другого словаря?
Имеется словарь с вложенными словарями и список словарей:
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}]