我知道这个问题已被多次覆盖,但我的要求是不同的.
我有一个列表: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,但如果长度不完全可分,则会抛出错误.
小智 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库的更多信息。
我想出了以下解决方案:
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从第二个元素开始获取每个元素,依此类推。这样就完成了任务。
拿走我的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)
我的答案是简单地使用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]]
以下解决方案具有许多优点:
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链接。
一种方法是使最后一个列表不均匀,而其余列表均匀。这可以按如下方式完成:
>>> 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)