Python将列表拆分为n个块

use*_*110 21 python

我知道这个问题已被多次覆盖,但我的要求是不同的.

我有一个列表:range(1, 26).我想把这个列表分成一个固定的数字n.假设n = 6.

>>> x
[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]
>>> l = [ x [i:i + 6] for i in range(0, len(x), 6) ]
>>> l
[[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]]
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我没有获得6个块(六个子列表包含原始列表的元素).如何以这样的方式划分列表,使得我得到n可能是偶数或不均匀的块

Jas*_*ell 38

使用numpy

>>> import numpy
>>> x = range(25)
>>> l = numpy.array_split(numpy.array(x),6)
Run Code Online (Sandbox Code Playgroud)

要么

>>> import numpy
>>> x = numpy.arange(25)
>>> l = numpy.array_split(x,6);
Run Code Online (Sandbox Code Playgroud)

您也可以使用numpy.split,但如果长度不完全可分,则会抛出错误.

  • 这仅适用于 numpy 支持的数字类型,而不是通用答案。 (3认同)
  • 我不知道为什么OP不接受这个答案。我发现一堆漂浮的“答案”实际上并没有用,但是确实可以。 (2认同)
  • 返回一个 numpy 数组列表,应明确注明(或显示)。 (2认同)
  • 我也不会接受这个,因为它需要导入.. 这可以通过很多其他方式完成.. 但一如既往,它取决于被拆分的数据.. 地图、[:] 等等。 (2认同)

小智 19

如果订单无关紧要:

def chunker_list(seq, size):
    return (seq[i::size] for i in range(size))

print(list(chunker_list([1, 2, 3, 4, 5], 2)))
>>> [[1, 3, 5], [2, 4]]

print(list(chunker_list([1, 2, 3, 4, 5], 3)))
>>> [[1, 4], [2, 5], [3]]

print(list(chunker_list([1, 2, 3, 4, 5], 4)))
>>> [[1, 5], [2], [3], [4]]

print(list(chunker_list([1, 2, 3, 4, 5], 5)))
>>> [[1], [2], [3], [4], [5]]

print(list(chunker_list([1, 2, 3, 4, 5], 6)))
>>> [[1], [2], [3], [4], [5], []]
Run Code Online (Sandbox Code Playgroud)


pyl*_*ang 10

more_itertools.divide 是解决这个问题的一种方法:

import more_itertools as mit


iterable = range(1, 26)
[list(c) for c in mit.divide(6, iterable)]
Run Code Online (Sandbox Code Playgroud)

输出

[[ 1,  2,  3,  4, 5],                       # remaining item
 [ 6,  7,  8,  9],
 [10, 11, 12, 13],
 [14, 15, 16, 17],
 [18, 19, 20, 21],
 [22, 23, 24, 25]]
Run Code Online (Sandbox Code Playgroud)

如图所示,如果 iterable 不能被均匀整除,则剩余的项目从第一个块到最后一个块分布。

此处查看有关该more_itertools库的更多信息。


Vla*_*lad 8

我想出了以下解决方案:

l = [x[i::n] for i in range(n)]
Run Code Online (Sandbox Code Playgroud)

例如:

n = 6
x = list(range(26))

l = [x[i::n] for i in range(n)]
print(l)
Run Code Online (Sandbox Code Playgroud)

输出:

[[0, 6, 12, 18, 24], [1, 7, 13, 19, 25], [2, 8, 14, 20], [3, 9, 15, 21], [4, 10, 16, 22], [5, 11, 17, 23]]
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,输出由n块组成,这些块具有大致相同数量的元素。


怎么运行的?

技巧是使用列表切片步长(两个分号后面的数字)并增加步进切片的偏移量。首先,它n从第一个元素开始获取每个元素,然后n从第二个元素开始获取每个元素,依此类推。这样就完成了任务。


pis*_*329 6

拿走我的2分钱..

from math import ceil

size = 3
seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

chunks = [
    seq[i * size:(i * size) + size]
    for i in range(ceil(len(seq) / size))
]

# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11]]

Run Code Online (Sandbox Code Playgroud)


Ara*_*syh 6

我的答案是简单地使用python内置的Slice:

# Assume x is our list which we wish to slice
x = range(1, 26)
# Assume we want to slice it to 6 equal chunks
result = []
for i in range(0, len(x), 6):
    slice_item = slice(i, i + 6, 1)
    result.append(x[slice_item])

# Result would be equal to 
Run Code Online (Sandbox Code Playgroud)

[[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]]

  • 这并不能回答问题。它分裂成大小为 6 的块,而不是 6 个块。 (4认同)

Jur*_*dom 5

以下解决方案具有许多优点:

  • 使用生成器产生结果。
  • 没有进口。
  • 列表是平衡的(如果将长度17的列表分成5,则永远不会得到4个大小为4的列表和一个大小为1的列表)。
def chunks(l, n):
    """Yield n number of striped chunks from l."""
    for i in range(0, n):
        yield l[i::n]
Run Code Online (Sandbox Code Playgroud)

上面的代码为l = range(16)和产生以下输出n = 6

[0, 6, 12]
[1, 7, 13]
[2, 8, 14]
[3, 9, 15]
[4, 10]
[5, 11]
Run Code Online (Sandbox Code Playgroud)

如果您需要块是顺序的而不是条带化的,请使用以下命令:

def chunks(l, n):
    """Yield n number of sequential chunks from l."""
    d, r = divmod(len(l), n)
    for i in range(n):
        si = (d+1)*(i if i < r else r) + d*(0 if i < r else i - r)
        yield l[si:si+(d+1 if i < r else d)]
Run Code Online (Sandbox Code Playgroud)

用于l = range(16)n = 6产生:

[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[9, 10, 11]
[12, 13]
[14, 15]
Run Code Online (Sandbox Code Playgroud)

有关生成器优点的更多信息,请参见此stackoverflow链接

  • 很好的顺序解决方案。我会指出 ```list(chunks(list(range(5)),6))``` 会生成 ```[[0], [1], [2], [3], [4 ],[]]``` 这很公平。 (2认同)

Suk*_*lra 2

一种方法是使最后一个列表不均匀,而其余列表均匀。这可以按如下方式完成:

>>> x
[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]
>>> m = len(x) // 6
>>> test = [x[i:i+m] for i in range(0, len(x), m)]
>>> test[-2:] = [test[-2] + test[-1]]
>>> test
[[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]]
Run Code Online (Sandbox Code Playgroud)