Представьте, что ваши столбцы:
1 a 1a
1 b 1b
2 a 2a
2 b 2b
Теперь попробуйте свой код:
>>> {x: {y:z} for x, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b'])}
{1: {'b': '1b'}, 2: {'b': '2b'}}
У вас есть цикл над кортежами: (1, 'a', '1a'), (1, 'b', '1b'), (2, 'a', '2a'), (2, 'b', '2b')
.
Первым элементом кортежа является «главный» ключ вашего словаря.Таким образом, dict {1: {'a':'1a'}}
после первого кортежа.
Затем наступает (1, 'b', '1b')
.Значение основного ключа 1
перезаписывается, и вхождение становится: {1: {'b':'1b'}}
.
Следующие шаги: {1: {'b':'1b'}, 2: {'a': '2a'}}
и {1: {'b': '1b'}, 2: {'b': '2b'}}
Чтобы избежать перезаписи, вы можете сделать:
>>> d = {}
>>> for x, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b']):
... d.setdefault(x, {}).update({y:z})
...
>>> d
{1: {'a': '1a', 'b': '1b'}, 2: {'a': '2a', 'b': '2b'}}
Идея состоит в том, чтобы создать новый диктдля каждого нового главного ключа (setdefault(..., {})
) и для обновления dict, связанного с главным ключом (update({y:z})
).
Если вам нужно понимание dict, этот будет работать:
>>> {x: {y:z for k, y, z in zip([1,1,2,2], ['a', 'b', 'a', 'b'], ['1a', '1b', '2a', '2b']) if k==x} for x in set([1,1,2,2])}
{1: {'a': '1a', 'b': '1b'}, 2: {'a': '2a', 'b': '2b'}}
Но он гораздо менее эффективен, чем цикл for
, потому что вы перебираете один цикл по первому столбцу, чтобы получить основные ключи, а затем еще раз по всем строкам для каждого главного ключа.