Как создать словарь, с вложенным словарем и сортировкой по дате на Python (3.9.6)

У меня есть список вывода логов биометрического контроля из текстового файла. Данные логи контроллера были отформатированы, и занесены как список. Данные значения уже до этого отсортированы, в список "заходит" первое событие, и последнее. В формате:

monitor_last_first = [
    ['Ваня', '8:33', '01.01.1995'],
    ['Ваня', '18:40', '01.01.1995'],
    ['Петя', '9:42', '01.01.1995'],
    ['Петя', '21:51', '01.01.1995'],
    ['Петя', '9:02', '02.01.1995'],
    ['Петя', '18:51', '02.01.1995'],
    ['Женя', '10:01', '01.01.1995'],
    ['Женя', '20:51', '01.01.1995'],

]

Мне необходимо создать словарь, с вложенным словарем. Значения для данного словаря должны браться из данного списка, а именно имя, и дата. После чего сортироваться, дабы в итоговом словаре было имя того кто пришел/ушел, и все его приходы/уходы, с привязкой по дате. В формате:

monitor_dict = {
    {'Ваня': {'01.01.1995': ['08:33', '18:40']}},
    {'Петя': {'01.01.1995': ['09:42', '21:51']}, {'02.01.1995': ['09:02', '18:51']},
    ['Женя': {'01.01.1995': ['10:01', '20:51']},

}

Проект домашний, не учебный/рабочий. По этому определенный алгоритм решения не нужен. Скорость тоже не играет сути, будет это выполняться 5 мкс, или 10 секунд не особо важно, так как скрипт запускается раз в месяц. Буду очень благодарен за хотя-бы наводку по решению, уже гуглил довольно много, решения не нашел.


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

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

Нужно просто налету сгенерировать словарь из словарей, состоящих из списка:

monitor_last_first = [
    ['Ваня', '8:33', '01.01.1995'],
    ['Ваня', '18:40', '01.01.1995'],
    ['Петя', '9:42', '01.01.1995'],
    ['Петя', '21:51', '01.01.1995'],
    ['Петя', '9:02', '02.01.1995'],
    ['Петя', '18:51', '02.01.1995'],
    ['Женя', '10:01', '01.01.1995'],
    ['Женя', '20:51', '01.01.1995'],
]

monitor_dict = dict()
for name, time, date in monitor_last_first:
    if name not in monitor_dict:
        monitor_dict[name] = dict()

    if date not in monitor_dict[name]:
        monitor_dict[name][date] = []

    monitor_dict[name][date].append(time)

Тот же код, что выше, но через defaultdict:

from collections import defaultdict

...

monitor_dict = defaultdict(lambda: defaultdict(list))
for name, time, date in monitor_last_first:
    monitor_dict[name][date].append(time)

Проверяем:

print(monitor_dict)

import json
print(json.dumps(monitor_dict, indent=4, ensure_ascii=False))

Результат:

{'Ваня': {'01.01.1995': ['8:33', '18:40']}, 'Петя': {'01.01.1995': ['9:42', '21:51'], '02.01.1995': ['9:02', '18:51']}, 'Женя': {'01.01.1995': ['10:01', '20:51']}}
{
    "Ваня": {
        "01.01.1995": [
            "8:33",
            "18:40"
        ]
    },
    "Петя": {
        "01.01.1995": [
            "9:42",
            "21:51"
        ],
        "02.01.1995": [
            "9:02",
            "18:51"
        ]
    },
    "Женя": {
        "01.01.1995": [
            "10:01",
            "20:51"
        ]
    }
}

PS.

Если нужно, что время добавлялось с лидирующим 0, то можно добавить в цикл строку:

time = time.zfill(5)
→ Ссылка
Автор решения: GrAnd

Решение в одну строчку, если не считать импортов... :)

from itertools import groupby
from operator import itemgetter

monitor_dict = dict([person, dict([date, list(map(itemgetter(1), times))] for date, times in groupby(visits, itemgetter(2)))] for person, visits in groupby(monitor_last_first, itemgetter(0)))
→ Ссылка