Сопряжение элементов из списков списка для формирования нового списка - PullRequest
0 голосов
/ 23 октября 2019

У меня есть список списков, подобный следующему,

a = [[ [1,2], [10, 3]], [[4,5], [6, 7]]]

Мне нужно связать большинство внутренних элементов списка таким образом,

a = [[[1, 10], [2, 3]], [[4, 6], [5, 7]]]. 

Простой подход был бы следующим,

pairings_ = []
for ind in a:
    pairings_.append([[x, y] for x in ind[0] for y in ind[1])

Это вызовет ошибку памяти, если списки внутри ind больше 2.
Например, если в ind [0], [1, 2], [10 было три внутренних списка, 3], [7, 8], тогда спаривание будет [1, 10, 7] и [2, 3, 8]. Предполагается, что длина внутреннего списка [[1, 10], [2, 3]] и [[4,6], [5, 7]] всегда будет равна.

Как бы яделать это самым питонным / тупым / эффективным способом из всех возможных?

Ответы [ 2 ]

5 голосов
/ 23 октября 2019

list(zip(*x)) - это хорошо известная идиома для «транспонирования» списков. В вашем случае:

In [267]: a = [[ [1,2], [10, 3]], [[4,5], [6, 7]]]                              
In [268]: [list(zip(*row)) for row in a]                                        
Out[268]: [[(1, 10), (2, 3)], [(4, 6), (5, 7)]]

Массив transpose удобен и выразителен, но создание массива из списка может быть дорогостоящим.

In [272]: timeit [list(zip(*row)) for row in a]                                 
1.58 µs ± 23.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [273]: timeit np.transpose(a, (0,2,1)).tolist()                              
11.8 µs ± 217 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Удаление массива, созданного из цикла синхронизации:

In [274]: %%timeit arr = np.array(a) 
     ...: np.transpose(arr, (0,2,1))                                                               
1.47 µs ± 11.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Но, как всегда при этих сравнениях по времени, результаты могут отличаться при работе с большими списками.

3 голосов
/ 23 октября 2019

Как бы я поступил так самым питонным / тупым / эффективным способом из всех возможных?

Вы можете использовать np.transpose и преобразовать его обратно в список.

In [1]: import numpy as np


In [2]: a = [[ [1,2], [10, 3]], [[4,5], [6, 7]]]


In [3]: np.transpose(a, (0,2,1)).tolist()

Out[3]: [[[1, 10], [2, 3]], [[4, 6], [5, 7]]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...