配对列表列表中的元素以形成新列表

til*_*era 0 python numpy

我有一个类似下面的列表,

a = [[ [1,2], [10, 3]], [[4,5], [6, 7]]]
Run Code Online (Sandbox Code Playgroud)

我需要以这种方式配对最里面的列表元素,

a = [[[1, 10], [2, 3]], [[4, 6], [5, 7]]]. 
Run Code Online (Sandbox Code Playgroud)

直接的方法如下:

pairings_ = []
for ind in a:
    pairings_.append([[x, y] for x in ind[0] for y in ind[1])
Run Code Online (Sandbox Code Playgroud)

如果ind中的列表大于2
,则将导致内存错误。例如,如果ind [0],[1、2],[ 10、3 ],[7、8]中有三个内部列表,则配对分别为[1、10、7]和[2、3、8]。假设[[1,10],[2,3]]和[[4,6],[5,7]]的内部列表的长度将始终相等。

我将如何以最pythonic / numpy /高效的方式去做呢?

hpa*_*ulj 5

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)]]
Run Code Online (Sandbox Code Playgroud)

数组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)
Run Code Online (Sandbox Code Playgroud)

从时序循环中删除创建的数组:

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)
Run Code Online (Sandbox Code Playgroud)

但是,与这些时序比较一样,使用较大的列表时结果可能会有所不同。