如何将任意长度的列表拆分为大小相等的块?
请参阅如果数据结果将直接用于循环,并且不需要存储,则如何以块形式遍历列表。
对于字符串输入的同一问题,请参见每n个字符拆分字符串?。相同的技术通常适用,但也有一些变化。
如何将任意长度的列表拆分为大小相等的块?
请参阅如果数据结果将直接用于循环,并且不需要存储,则如何以块形式遍历列表。
对于字符串输入的同一问题,请参见每n个字符拆分字符串?。相同的技术通常适用,但也有一些变化。
当前回答
def chunk(input, size):
return map(None, *([iter(input)] * size))
其他回答
toolz库具有如下分区函数:
from toolz.itertoolz.core import partition
list(partition(2, [1, 2, 3, 4]))
[(1, 2), (3, 4)]
因为这里的每个人都在谈论迭代器。boltons有一个完美的方法,叫做iterutils.chunked_iter。
from boltons import iterutils
list(iterutils.chunked_iter(list(range(50)), 11))
输出:
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
[22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32],
[33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43],
[44, 45, 46, 47, 48, 49]]
但如果您不想在内存上手下留情,您可以使用旧方法,首先使用iterutils.chunked存储完整列表。
我在这个问题的副本中看到了最棒的Python式答案:
from itertools import zip_longest
a = range(1, 16)
i = iter(a)
r = list(zip_longest(i, i, i))
>>> print(r)
[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15)]
您可以为任何n创建n元组。如果a=范围(1,15),那么结果将是:
[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, None)]
如果列表被平均划分,那么可以用zip替换zip_langest,否则三元组(13、14、None)将丢失。上面使用了Python 3。对于Python 2,请使用izip_length。
这里有一个使用itertools.groupby的想法:
def chunks(l, n):
c = itertools.count()
return (it for _, it in itertools.groupby(l, lambda x: next(c)//n))
这将返回一个生成器。如果需要列表列表,只需将最后一行替换为
return [list(it) for _, it in itertools.groupby(l, lambda x: next(c)//n)]
返回列表列表示例:
>>> chunks('abcdefghij', 4)
[['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j']]
(因此,是的,这会受到“矮子问题”的影响,在特定情况下,这可能是问题,也可能不是问题。)
上面的答案(由koffein给出)有一个小问题:列表总是被分割成相等数量的分割,而不是每个分区的项目数相等。这是我的版本。“//chs+1”考虑到项目的数量可能不能完全除以分区大小,因此最后一个分区将仅被部分填充。
# Given 'l' is your list
chs = 12 # Your chunksize
partitioned = [ l[i*chs:(i*chs)+chs] for i in range((len(l) // chs)+1) ]