Python сгруппировать список словарей по полям наиболее коротко

Такая задачка (пример ниже) на наиболее короткую запись

Дано:

Список словарей, у всех словарей одинаковый набор полей

Требуется:

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

Пример:

Начальный список:

role_list = [
    {'id_role': 1, 'role_name': 'a', 'id_pool': 1, 'ad_name': 'test', 'id_object': 1, 'id_action': 1},
    {'id_role': 1, 'role_name': 'a', 'id_pool': 1, 'ad_name': 'test', 'id_object': 1, 'id_action': 4},
    {'id_role': 2, 'role_name': 'b', 'id_pool': 1, 'ad_name': 'test', 'id_object': 1, 'id_action': 2},
    {'id_role': 3, 'role_name': 'c', 'id_pool': None, 'ad_name': None, 'id_object': 2, 'id_action': 3},
]

Принцип группировки:

  1. Сначала группируем по id_role, сохраняя role_name, id_pool и ad_name (они будут гарантированно одинаковыми), остальное группируем в поле permissions, т.е. собираем все словари с одинаковым id_role в словарь

{'id_role': a, 'ad_name': b, 'id_pool': c, 'ad_name': d, 'permissions': [...]}

  1. В поле permissions группируем по полю id_object, остальное помещаем в поле actions, т.е. поле permissions будет таким списком:

[{'id_object': a, 'actions': [...]}, {'id_object': b, 'actions': [...]}]

  1. В поле actions просто добавляем все значения соответствующих полей id_action

Итоговый результат (grouped_roles):

role_list = role_list = [
    {'id_role': 1, 'role_name': 'a', 'id_pool': 1, 'ad_name': 'test', 'id_object': 1, 'id_action': 1},
    {'id_role': 1, 'role_name': 'a', 'id_pool': 1, 'ad_name': 'test', 'id_object': 1, 'id_action': 4},
    {'id_role': 2, 'role_name': 'b', 'id_pool': 1, 'ad_name': 'test', 'id_object': 1, 'id_action': 2},
    {'id_role': 3, 'role_name': 'c', 'id_pool': None, 'ad_name': None, 'id_object': 2, 'id_action': 3},
]

grouped_roles = [
    {
        'id_role': 1,
        'role_name': 'a',
        'id_pool': 1,
        'ad_name': 'test',
        'permissions': [{
            'id_object': 1,
            'actions': [1, 4]
        }]
    },
    {
        'id_role': 2,
        'role_name': 'b',
        'id_pool': 1,
        'ad_name': 'test',
        'permissions': [{
            'id_object': 1,
            'actions': [2]
        }]
    },
    {
        'id_role': 3,
        'role_name': 'c',
        'id_pool': None,
        'ad_name': None,
        'permissions': [{
            'id_object': 2,
            'actions': [3]
        }]
    },
]

Есть ли возможность написать такое наиболее коротко, например, с помощью пробега по массивам [foo(r) for r in role_list] или еще как-нибудь, может с использованием NumPy?


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