Транспонирование вложенных списков
Есть объекта типа Dict[int, List[int]], пример:
from collections import defaultdict
example = defaultdict(list)
for i in range(5):
example[i] = list(range(9))
example
defaultdict(list,
{0: [0, 1, 2, 3, 4, 5],
1: [0, 1, 2, 3, 4, 5],
2: [0, 1, 2, 3, 4, 5],
3: [0, 1, 2, 3, 4, 5],
4: [0, 1, 2, 3, 4, 5]})
Нужно получить объект типа List[List[int]]:
modified_example
[[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4],
[5, 5, 5, 5, 5]]
Нашел 2 способа получить желаемое:
np.array(list(example.values())).T
3.07 µs ± 7.74 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
[[x[i] for x in example.values()] for i in range(len(example[0]))]
2.39 µs ± 8.38 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Какие еще альтернативные способы существуют? Какой из них более pythonic?
Ответы (1 шт):
Автор решения: Dmitry Sokolov
→ Ссылка
Есть вариант с помощью zip():
[list(i) for i in zip(*(x for x in example.values()))]
Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:37:02) [MSC v.1924 64 bit (AMD64)] on win32
>>> import timeit
>>> import pprint
>>> from collections import defaultdict
...
... example = defaultdict(list)
... for i in range(5):
... example[i] = list(range(9))
...
>>> pprint.pp(example)
defaultdict(<class 'list'>,
{0: [0, 1, 2, 3, 4, 5, 6, 7, 8],
1: [0, 1, 2, 3, 4, 5, 6, 7, 8],
2: [0, 1, 2, 3, 4, 5, 6, 7, 8],
3: [0, 1, 2, 3, 4, 5, 6, 7, 8],
4: [0, 1, 2, 3, 4, 5, 6, 7, 8]})
>>> timeit.repeat('[list(i) for i in zip(*(x for x in example.values()))]', number=100000, globals=globals())
[0.17644459999996798, 0.17067040000006273, 0.17037619999996423, 0.17163510000000315, 0.16984129999991637]
>>> timeit.repeat('[[x[i] for x in example.values()] for i in range(len(example[0]))]', number=100000, globals=globals())
[0.3348793000000114, 0.3326208000000861, 0.3421081999999842, 0.35968720000005305, 0.36050719999980174]