Python 在嵌套列表中将列表分解为子列表

Python 在嵌套列表中将列表分解为子列表,python,numpy,Python,Numpy,我有一个列表,如下所示: l = [([1, 0.0, 50.0, 2, 0.0, 50.0], [1, 1.9, 1]), ([1, 0.0, 50.0, 2, 0.0, 50.0], [2, 1.9, 1])] 我想转换此列表,使新结构如下所示: goal = [([1, 0.0, 50.0], [2, 0.0, 50.0], [1, 1.9, 1]), ([1, 0.0, 50.0], [2, 0.0, 50.0], [2, 1.9, 1])] 也就是说,每个元组中的第一个列

我有一个列表,如下所示:

l = [([1, 0.0, 50.0, 2, 0.0, 50.0], [1, 1.9, 1]),
     ([1, 0.0, 50.0, 2, 0.0, 50.0], [2, 1.9, 1])]
我想转换此列表,使新结构如下所示:

goal = [([1, 0.0, 50.0], [2, 0.0, 50.0], [1, 1.9, 1]), ([1, 0.0, 50.0], [2, 0.0, 50.0], [2, 1.9, 1])]
也就是说,每个元组中的第一个列表被分解为长度为3的子列表

我尝试了下面的方法,但由于各种转换返回numpy数组而导致混乱,所以我被卡住了。 此外,此操作可能发生在l的大型变体上,因此应为性能友好型/就地(?)


您可以在列表中使用
itertools.chain

In [23]: from itertools import chain

In [24]: [tuple(chain.from_iterable((i[:3], i[3:]) if len(i) > 3 else [i] for i in sub)) for sub in l]
Out[24]: 
[([1, 0.0, 50.0], [2, 0.0, 50.0], [1, 1.9, 1]),
 ([1, 0.0, 50.0], [2, 0.0, 50.0], [2, 1.9, 1])]
通常,您可以使用
itertools.islice
将子列表切成三份:

In [37]: [tuple(list(islice(i,t,t+3)) if len(i) > 3 else i for i in sub for t in range(0, len(i), 3)) for sub in l]
Out[37]: 
[([1, 0.0, 50.0], [2, 0.0, 50.0], [1, 1.9, 1]),
 ([1, 0.0, 50.0], [2, 0.0, 50.0], [2, 1.9, 1])]

在我的评论中,我反对为此使用
np.array
,因为

In [241]: np.array(l)
Out[241]: 
array([[[1, 0.0, 50.0, 2, 0.0, 50.0], [1, 1.9, 1]],
       [[1, 0.0, 50.0, 2, 0.0, 50.0], [2, 1.9, 1]]], dtype=object)
是一个对象数组。但是,阵列版本可以通过重塑使拆分列表变得容易

In [240]: [np.array(x[0]+x[1]).reshape(-1,3).tolist() for x in l]
Out[240]: 
[[[1.0, 0.0, 50.0], [2.0, 0.0, 50.0], [1.0, 1.9, 1.0]],
 [[1.0, 0.0, 50.0], [2.0, 0.0, 50.0], [2.0, 1.9, 1.0]]]
如果必须是元组而不是列表,则添加
[tuple(n..

我正在做一些技巧。由于第二个项目的长度与所需拆分(3)的长度相同,我只是在开始时将它们连接在一起,而不必担心以后会这样做。然后数组整形,然后执行
tolist
有效地拆分数组

In [246]: np.reshape(x[0]+x[1],(-1,3))
Out[246]: 
array([[  1. ,   0. ,  50. ],
       [  2. ,   0. ,  50. ],
       [  1. ,   1.9,   1. ]])
这取决于能否将子列表平均拆分3

阵列往返可能比等效的
itertools
code慢


in-place
将不起作用,因为您有一个元组列表。您可以替换这些元组,但不能修改它们。如果它们是列表,您可以像这样在拆分中拼接:

In [248]: x
Out[248]: ([1, 0.0, 50.0, 2, 0.0, 50.0], [1, 1.9, 1])
In [249]: xl=list(x)

In [250]: xl[0:1] = [xl[0][:3],xl[0][3:]]   # or the split of your choice
In [251]: xl
Out[251]: [[1, 0.0, 50.0], [2, 0.0, 50.0], [1, 1.9, 1]]
通常,创建新列表和元组比就地更改更方便。复制列表只意味着创建相同指针的新列表


由于可以从列表的末尾切掉
@Kasramvd的
islice
版本可以简化为:

[tuple([i[t:t+3]  for i in sub for t in range(0, len(i), 3)]) for sub in l]
[tuple([i[t:t+3]  for i in sub for t in range(0, len(i), 3)]) for sub in l]