Транспонирование вложенных списков

Есть объекта типа 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 способа получить желаемое:

  1. np.array(list(example.values())).T

3.07 µs ± 7.74 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

  1. [[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]
→ Ссылка