Объяснить работу defaultdict
Пытаюсь с помощью defaultdict группировать данные, благодаря свойству уникальности ключей в словаре. Есть переменная со списком кортежей: request = [(1, '[email protected]'),(2, '[email protected]'),(3, '[email protected]'),(4, '[email protected]'),(5, '[email protected]')]. Я осуществляю группировку по email, предварительно переводя его в нижний регистр таким образом:
players = defaultdict(list)
{players[_i[1].lower()].append(_i[0]) for _i in tqdm.tqdm(request) if _i[0] not in players[_i[1]]}
По моим ожиданиям ответ должен получиться такой:
{
'[email protected]': [1, 2],
'[email protected]': [3],
'[email protected]': [4, 5]
}
Но почему-то в результате получаю такое:
{
'[email protected]': [1, 2],
'[email protected]': [],
'[email protected]': [3],
'[email protected]': [4, 5],
'[email protected]': []
}
Можете объяснить, почему?
P.S. tqdm сторонняя библиотека для визуализации процесса выполнения прохода по списку.
Ответы (1 шт):
потому что запись добавляется в словарь в момент попытки обратиться к ней. если ключа нет.
players = defaultdict(list)
{players[_i[1].lower()].append(_i[0]) for _i in tqdm.tqdm(request) if _i[0] not in players[_i[1]]}
Давайте для начала перепишем пример. чтобы мне было проще указать место.
1for _i in tqdm.tqdm(request):
2 if _i[0] not in players[_i[1]]:
3 players[_i[1].lower()].append(_i[0])
во второй строке в условии идет получение значения по ключу players[_i[1]]. в этот самый момент добавляется запись. если ключа нет. т.е. вместо получения стандартной ошибки KeyError. а так как тут нет перевода в нижний регистр то вы и получаете то что получаете.
players = defaultdict(list)
{players[_i[1].lower()].append(_i[0]) for _i in tqdm.tqdm(request) if _i[0] not in players[_i[1].lower()]}
можно убрать проверку уникальности
players = defaultdict(set)
{players[_i[1].lower()].add(_i[0]) for _i in tqdm.tqdm(request)}