如何将任意长度的列表拆分为大小相等的块?
请参阅如果数据结果将直接用于循环,并且不需要存储,则如何以块形式遍历列表。
对于字符串输入的同一问题,请参见每n个字符拆分字符串?。相同的技术通常适用,但也有一些变化。
如何将任意长度的列表拆分为大小相等的块?
请参阅如果数据结果将直接用于循环,并且不需要存储,则如何以块形式遍历列表。
对于字符串输入的同一问题,请参见每n个字符拆分字符串?。相同的技术通常适用,但也有一些变化。
当前回答
还有一个解决方案
def make_chunks(data, chunk_size):
while data:
chunk, data = data[:chunk_size], data[chunk_size:]
yield chunk
>>> for chunk in make_chunks([1, 2, 3, 4, 5, 6, 7], 2):
... print chunk
...
[1, 2]
[3, 4]
[5, 6]
[7]
>>>
其他回答
这项任务可以在公认答案中使用生成器轻松完成。我正在添加实现长度方法的类实现,这可能对某些人有用。我需要知道进度(使用tqdm),所以生成器应该返回块的数量。
class ChunksIterator(object):
def __init__(self, data, n):
self._data = data
self._l = len(data)
self._n = n
def __iter__(self):
for i in range(0, self._l, self._n):
yield self._data[i:i + self._n]
def __len__(self):
rem = 1 if self._l % self._n != 0 else 0
return self._l // self._n + rem
用法:
it = ChunksIterator([1,2,3,4,5,6,7,8,9], 2)
print(len(it))
for i in it:
print(i)
没有魔力,但简单而正确:
def chunks(iterable, n):
"""Yield successive n-sized chunks from iterable."""
values = []
for i, item in enumerate(iterable, 1):
values.append(item)
if i % n == 0:
yield values
values = []
if values:
yield values
抽象将是
l = [1,2,3,4,5,6,7,8,9]
n = 3
outList = []
for i in range(n, len(l) + n, n):
outList.append(l[i-n:i])
print(outList)
这将打印:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
我创建了这两个漂亮的一行程序,它们既高效又懒惰,输入和输出都是可迭代的,而且它们不依赖于任何模块:
首先,一行是完全懒惰的,这意味着它返回迭代器生成迭代器(即,生成的每个块都是迭代器对块的元素进行迭代),如果块非常大或元素一个接一个地缓慢生成,并且在生成时应立即可用,则此版本适用于这种情况:
在线试用!
chunk_iters = lambda it, n: ((e for i, g in enumerate(((f,), cit)) for j, e in zip(range((1, n - 1)[i]), g)) for cit in (iter(it),) for f in cit)
第二行返回生成列表的迭代器。一旦整个块的元素通过输入迭代器变得可用,或者到达最后一个块的最后一个元素,就会生成每个列表。如果输入元素快速生成或立即全部可用,则应使用此版本。应该使用其他明智的第一个更懒惰的一行代码版本。
在线试用!
chunk_lists = lambda it, n: (l for l in ([],) for i, g in enumerate((it, ((),))) for e in g for l in (l[:len(l) % n] + [e][:1 - i],) if (len(l) % n == 0) != i)
此外,我还提供了第一个chunk_iter的多行版本一行,它返回迭代器生成另一个迭代器(遍历每个chunk的元素):
在线试用!
def chunk_iters(it, n):
cit = iter(it)
def one_chunk(f):
yield f
for i, e in zip(range(n - 1), cit):
yield e
for f in cit:
yield one_chunk(f)
还可以将utilspie库的get_chunks函数用作:
>>> from utilspie import iterutils
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(iterutils.get_chunks(a, 5))
[[1, 2, 3, 4, 5], [6, 7, 8, 9]]
您可以通过pip安装utilspie:
sudo pip install utilspie
免责声明:我是utilspie库的创建者。