Из списка словарей в python Django как отфильтровать/найти и наибольшую стоимость приза на пользователя в день

Я хочу узнать в день для каждого пользователя, какой самый высокий приз он выиграл

my_list = [{'id': 1, 'user_id': 4, 'date': datetime.datetime(2022, 9, 9), 'prize': '45.00'},
{'id': 2, 'user_id': 5, 'date': datetime.datetime(2022, 9, 5), 'prize': '85.00'},
{'id': 3, 'user_id': 5, 'date': datetime.datetime(2022, 9, 5), 'prize': '35.00'},
{'id': 4, 'user_id': 4, 'date': datetime.datetime(2022, 9, 9), 'prize': '95.00'},
{'id': 5, 'user_id': 3, 'date': datetime.datetime(2022, 9, 9), 'prize': '10.00'},
{'id': 6, 'user_id': 6, 'date': datetime.datetime(2022, 9, 5), 'prize': '15.00'}]

результат должен быть следующим

result = [{'id': 2, 'user_id': 5, 'date': datetime.datetime(2022, 9, 5), 'prize': '85.00'},
{'id': 4, 'user_id': 4, 'date': datetime.datetime(2022, 9, 9), 'prize': '95.00'},
{'id': 5, 'user_id': 3, 'date': datetime.datetime(2022, 9, 9), 'prize': '10.00'},
{'id': 6, 'user_id': 6, 'date': datetime.datetime(2022, 9, 5), 'prize': '15.00'}]

В приведенном выше примере user_id=4 имеет 2 приза на дату(2022, 9, 5), т.е. $45 и $95. Среди этих двух призов мы должны выбрать запись с наибольшей стоимостью $95

Вы можете использовать groupby из itertools и передавать данные в каждой группе в max с помощью лямбда-функции для параметра key. Но поскольку в этом решении данные должны быть отсортированы, вы можете сначала отсортировать данные, затем сгруппировать их и, наконец, взять максимум. И вы можете взять id значения для этих идентификаторов, затем окончательно отфильтровать записи по этим идентификаторам:

from itertools import groupby

[x for x in my_list
if x['id'] in (max(v, key=lambda x: float(x['prize']))['id']
               for k, v in groupby(sorted(my_list,
                                          key=lambda x: (x['user_id'], x['date'])),
                                   key=lambda x: (x['user_id'], x['date'])))]

OUTPUT

[   
    {   'date': datetime.datetime(2022, 9, 5, 0, 0),
        'id': 2,
        'prize': '85.00',
        'user_id': 5},
    {   'date': datetime.datetime(2022, 9, 9, 0, 0),
        'id': 4,
        'prize': '95.00',
        'user_id': 4},
    {   'date': datetime.datetime(2022, 9, 9, 0, 0),
        'id': 5,
        'prize': '10.00',
        'user_id': 3},
    {   'date': datetime.datetime(2022, 9, 5, 0, 0),
        'id': 6,
        'prize': '15.00',
        'user_id': 6}
]

Попробуйте этот запрос.

from django.db.models.aggregates import Max
Model.objects.all().values('user_id','date').annotate(max_prize=Max('prize'))
Вернуться на верх