如何在 python 中将每 5 个列表组合在一个列表中?



我有一个很大的列表列表,例如:

list = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]

我想将每 5 个列表合并为一个元素列表,依此类推。 我在一个列表中总共有150995个列表。

预期产出:

new_list = [['a' , 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

我尝试使用以下代码。 但它被扁平化为一个列表。

list(zip(*list)[0])

我该怎么做?

你基本上想要对大小均匀的列表块进行分组。可以使用itertools.chain和切片,range和 5 步长

import itertools
lst = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]
result = [list(itertools.chain.from_iterable(itertools.islice(lst,i,i+5))) for i in range(0,len(lst),5)]

print(result)

结果:

[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

笔记:

  • 使用itertools.islice可避免创建无用list对象的标准lst[i:i+5]切片
  • 即使元素的数量不能被 5 整除,它也能工作。

给定:

>>> li = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]

你可以做:

>>> list(map(list, zip(*[iter([e for sublist in li for e in sublist])]*5)))
[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

>>> [[e for sublist in lst[i:i+5] for e in sublist] for i in range(0,len(lst),5)]
[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

这个解决方案很方便,因为它除了numpy之外什么都不用

如果您的列表始终包含可被 5 整除的元素,则

import numpy as np
oldlist = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]
newlist = np.reshape(oldlist,(len(oldlist)//5,5)).T.tolist()

新列表将具有您想要的输出

[['a' , 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

使用itertools.chain将列表展平,itertools.zip_longest将 elemensts 分组为 5 个块

>>> from itertools import zip_longest, chain
>>> n = 5
>>> list(zip_longest(*[chain(*List)]*n))    
[('a', 'b', 'c', '1234', 'd'), ('e', 'g', 'h', 'i', '56')]

如果您对元组列表的结果不满意,您可以使用map将各个元素从元组转换为列表

>>> list(map(list, zip_longest(*[chain(*List)]*5)))
[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

已经有很多很好的解决方案了。我只是想添加另一种可能性,即使用自定义Iterator如下所示:

from itertools import chain

class MyIter:
def __init__(self, lists,n_first):
self.lists = lists
self.index = 0
self.n_first = n_first
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.lists):
temp = list(chain(*self.lists[self.index:min(self.index+self.n_first,len(self.lists))]))
self.index += self.n_first
return temp
else:
raise StopIteration
_list = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]
print(list(MyIter(_list,5)))

假设len(list)是 5 的倍数,则以下解决方案有效:

list = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]
row = int(len(list)/5)
new_list = [i.tolist() for i in np.array(list).reshape((row,5))]
print (new_list)

导致

[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

这是一个非库列表理解解决方案:

>>> L = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]
>>> [[j[0] for j in L[i:i+5]] for i in range(0, len(L), 5)]
[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

顺便说一下,调用列表list重新定义内置函数。

最新更新