我有一个很大的列表列表,例如:
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
重新定义内置函数。