如何将Python列表分成相等大小的块?

26

有没有简单的方法将[1,2,3,4,5,6,7,8,9]转换为[[1,2,3],[4,5,6],[7,8,9]],而不需要明确使用for循环?


如果列表中的项目数量不能被块大小整除,应该发生什么? - Tim Pietzcker
1
这个之前已经被问过了。 - dawg
5个回答

67

4
解释一下吧 :P - Serdalis
1
之前已经解释过了,但我会找一个链接。 - jamylak
3
非常聪明,但我猜这是符合Python风格的。 - ddaa
34
请注意,这将丢弃不完整的块。如果您使用x=[1,2,3,4,5,6,7]测试它,那么您只会得到两个块,并且数字7将被丢弃。(当然,如果这是您想要的结果,那就没问题,但如果不是,请小心!) - gimboland
@rbaleksandar 没有唯一的块大小可确定。每个列表都可以分成相等的 1N(列表中的项目数)块,或者是 N 的某个因子。对于这个问题没有一个特定的最佳数字,如果需要,可以根据个人喜好来考虑该数字。 - jamylak
显示剩余8条评论

14
如果您真的希望子元素是列表而不是元组:
In [9]: [list(t) for t in zip(*[iter(range(1,10))]*3)]
Out[9]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

或者,如果你想包含那些会被 zip 截断的剩余元素,可以使用切片语法:

In [16]: l=range(14)

In [17]: [l[i:i+3] for i in range(0,len(l),3)]
Out[17]: [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13]]

1
这个版本不会丢弃“剩余”的余数,所以这是我的选择。 - chirale

10

你也可以在这里使用numpy.reshape

import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9])

new_x = np.reshape(x, (3,3))

结果:

>>> new_x
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

看起来非常干净 ;) 但是...仅仅为了这个目的将整个numpy添加到项目中;) - andilabs

8
>>> map(None,*[iter(s)]*3)
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]

1
这似乎只是我代码的可读性较差的版本... - jamylak
这段精确的代码在jamylak帖子中提供的链接的被接受的答案中。 - Akavall
我想了解它可以运行是可以的,但是由于我之前说过的原因,我不建议使用它。 - jamylak
5
@jamylak,实际上,这段代码的功能与你的代码略有不同。看一下map(None, *[iter(range(10))]*3)zip(*[iter(range(10))]*3)的结果。由于OP没有指定想要哪种行为,这个答案是有效的。 - senderle
1
@senderle,我会使用izip_longest。这也是itertools示例中使用的。 - jamylak
jamylak的版本如果最后一个元组不恰好有三个元素,则会丢失该元组,而shiva的版本则使用None来填充最后一个元组,但它会将所有原始元素放入答案中。 - alemol

0
这是一个使用递归的远不如以前的方式:
from itertools import chain

def groupsof(n, xs):
    if len(xs) < n:
        return [xs]
    else:
        return chain([xs[0:n]], groupsof(n, xs[n:]))

print list(groupsof(3, [1,2,3,4,5,6,7,8,9,10,11,12,13]))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接