将几个子列表重新排列为两个子列表

时间:2013-11-11 13:34:41

标签: python list

我有一个如下所示的主列表:

a = [ [[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]], [[13,14,15],[16,17,18]] ]

我需要重新排列它,使它看起来像这样:

b = [[1,2,3,7,8,9,13,14,15], [4,5,6,10,11,12,16,17,18]]

ie:获取主列表的每个子列表中第一个子列表中的所有元素,并将它们放在新列表的0位置的单个子列表中,然后对第二个子列表执行相同的操作并放入此新列表的位置1中的单个子列表中的所有元素。

我已经尝试zip结合Making a flat list out of list of lists in Python中给出的解决方案,但我无法让它发挥作用。

4 个答案:

答案 0 :(得分:2)

zip*itertools.chain.from_iterable一起使用。

>>> from itertools import chain, izip
>>> [list(chain.from_iterable(x)) for x in zip(*a)] #or `izip`
[[1, 2, 3, 7, 8, 9, 13, 14, 15], [4, 5, 6, 10, 11, 12, 16, 17, 18]]

此处zip(*a)返回:

[([1, 2, 3], [7, 8, 9], [13, 14, 15]), ([4, 5, 6], [10, 11, 12], [16, 17, 18])]

现在,您可以使用chain.from_iterable(x)展平其项目。

时间比较:

In [1]: from itertools import izip, chain
In [2]: a = [[[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]], [[13,14,15],[16,17,18]]]
In [3]: %timeit [list(chain.from_iterable(x)) for x in zip(*a)]
100000 loops, best of 3: 3.71 us per loop
In [4]: %timeit [[i for v in r for i in v] for r in zip(*a)]
100000 loops, best of 3: 2.73 us per loop

In [5]: b = a *100
In [6]: %timeit [list(chain.from_iterable(x)) for x in zip(*b)]
10000 loops, best of 3: 97.6 us per loop
In [7]: %timeit [list(chain.from_iterable(x)) for x in izip(*b)]
10000 loops, best of 3: 97.6 us per loop
In [8]: %timeit [[i for v in r for i in v] for r in zip(*b)]
10000 loops, best of 3: 144 us per loop
In [9]: %timeit [[i for v in r for i in v] for r in izip(*b)]
10000 loops, best of 3: 143 us per loop

In [10]: c = a*10000
In [11]: %timeit [list(chain.from_iterable(x)) for x in zip(*c)]
100 loops, best of 3: 12.9 ms per loop
In [12]: %timeit [list(chain.from_iterable(x)) for x in izip(*c)]
100 loops, best of 3: 12.3 ms per loop
In [13]: %timeit [[i for v in r for i in v] for r in zip(*c)]
100 loops, best of 3: 17 ms per loop
In [14]: %timeit [[i for v in r for i in v] for r in izip(*c)]
100 loops, best of 3: 17.1 ms per loop

答案 1 :(得分:1)

>>> a = [[[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]], [[13,14,15],[16,17,18]]]
>>>
>>> [[i for v in r for i in v] for r in zip(*a)]
[[1, 2, 3, 7, 8, 9, 13, 14, 15], [4, 5, 6, 10, 11, 12, 16, 17, 18]]

请参阅:zip()

答案 2 :(得分:1)

a = [ [[1,2,3],[4,5,6]], [[7,8,9],[10,11,12]], [[13,14,15],[16,17,18]] ]
b = [[item for sitems in items for item in sitems] for items in zip(*a)]
print b

<强>输出

[[1, 2, 3, 7, 8, 9, 13, 14, 15], [4, 5, 6, 10, 11, 12, 16, 17, 18]]

答案 3 :(得分:0)

列表可以通过使用带有空列表的sum()作为第一个元素来展平,因此您可以使用:

[sum((item[0] for item in a), []), sum((item[1] for item in a), [])]

或者,对于任意数量的内部元素:

[sum((item[i] for item in a), []) for i in range(len(a[0]))]