我有一个列表,其嵌套列表的大小可能会以2的倍数变化。目前,在此示例中,嵌套列表的长度为4。
a_list = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
根据长度,我试图打破列表,以最佳的pythonic方式得到以下结果:
a = [[1,2], [5,6], [9,10]]
b = [[3,4], [7,8], [11,12]]
如果嵌套列表的长度为6,那么
c = [[..], [..], [..]]
它是一种嵌套列表的转置,但在一行中有两组值不能转置。
答案 0 :(得分:6)
使用列表理解:
>>> a_list = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
>>> a = [x[:2] for x in a_list]
>>> b = [x[2:] for x in a_list]
>>> a
[[1, 2], [5, 6], [9, 10]]
>>> b
[[3, 4], [7, 8], [11, 12]]
更一般的解决方案:
>>> [[x[i:i+2] for x in a_list] for i in range(0, len(a_list[0]), 2)]
[[[1, 2], [5, 6], [9, 10]],
[[3, 4], [7, 8], [11, 12]]]
答案 1 :(得分:2)
我会毫不犹豫地称之为“pythonic”,因为它几乎难以辨认,但是:
>>> a, b = zip(*(zip(*[iter(s)]*2) for s in a_list))
>>> a
((1, 2), (5, 6), (9, 10))
>>> b
((3, 4), (7, 8), (11, 12))
也适用于6项目列表:
>>> a_list = [[1,2,3,4,100,102],[5,6,7,8,103,104],[9,10,11,12,105,106]]
>>> a, b, c = zip(*(zip(*[iter(s)]*2) for s in a_list))
>>> a
((1, 2), (5, 6), (9, 10))
>>> b
((3, 4), (7, 8), (11, 12))
>>> c
((100, 102), (103, 104), (105, 106))
答案 2 :(得分:1)
与falsetru的答案几乎相同,但首先将嵌套列表拆分为大小为2的块,然后将它们全部压缩在一起。
>>> a_list = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>>> zip(*([j[i*2: i*2 + 2] for i in range(len(j) / 2)] for j in a_list))
[([1, 2], [5, 6], [9, 10]), ([3, 4], [7, 8], [11, 12])]
>>> a_list = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
>>> zip(*([j[i*2: i*2 + 2] for i in range(len(j) / 2)] for j in a_list))
[([1, 2], [7, 8]), ([3, 4], [9, 10]), ([5, 6], [11, 12])]
>>> a_list = [[1,2,3,4,100,102],[5,6,7,8,103,104],[9,10,11,12,105,106]]
>>> zip(*([j[i*2: i*2 + 2] for i in range(len(j) / 2)] for j in a_list))
[([1, 2], [5, 6], [9, 10]), ([3, 4], [7, 8], [11, 12]), ([100, 102], [103, 104], [105, 106])]
答案 3 :(得分:1)
快速方法是使用numpy.hsplit
:
>>> import numpy
>>> numpy.hsplit(numpy.array(a_list),2)
[array([[ 1, 2],[ 5, 6],[ 9, 10]]),array([[ 3, 4],[ 7, 8],[11, 12]])]
答案 4 :(得分:1)
由于可读性是pythonic,这里是一个更简单的基于迭代器的解决方案(没有@Zero用来将其变成单行的简洁技巧):
首先,将列表[1,2,3,4,5,6]
转换为[(1, 2), (3, 4), (5, 6)]
的迭代器。
def pairs(lst):
it=iter(lst)
return list(zip(it, it)) # Return a list of pairs drawn from the same iterator
列表a_list
可以转换为这样的对列表的列表,如下所示:
a_list = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
pair_list = [ pairs(row) for row in a_list ]
最后,我们需要有效地转置这个列表,列出每个子列表中的第一对/元素,另一个列表中的第二个,等等。transposing a list的一个很好的习语是zip(*some_list)
。让我们使用它来进行OP请求的转换:
a, b = zip(*pair_list)
或在一个列表中收集任意数量的生成列表:
results = list( zip(*pair_list) )
随意将这些包装成一行(虽然我不会):
results = list(zip( *(pairs(row) for row in a_list) ))