假设我有一个数字l
,我想将其分成大致相等的n
块。例如:
l = 11
n = 3
step = 1 + l // n
for start in range(0, l, step):
stop = min(l, start+step)
print(start, stop)
在这种情况下,第一个块(块0
)从0到4(5个元素),下一个块(块1
)从4到8(5个元素),并且最后一块(块2
)稍小,从8到11(4个元素)。当然,l
和n
的值可以变化,但是两个值将始终为正整数,并且n
始终小于l
。
我需要做的是生成一个列表,该列表将以循环方式遍历每个块,并将一些块信息附加到列表中。该列表应包含一个块编号(即0
,1
或2
)的元组和该块中的下一个可用的起始值(直到该块由stop
值)。因此,输出列表将是:
[(0,0), (1,4), (2,8), (0,1), (1,5), (2,9), (0,2), (1,6), (2,10), (0,3), (1,7)]
请注意,最后一个块比前两个块具有最后一个元素。无论解决方案是什么,它都需要适用于任何l
和n
(只要两个值都是正整数,并且n
始终小于l
)。为简单起见,您可以假设l
小于100,000,000。
生成此列表的最佳方法是什么?
答案 0 :(得分:1)
对问题的两个级别使用两个循环。外循环通过range(step)
中的所有数字作为起点。从那里开始,使用该值作为您已经编写的内部循环的起点。请注意,您必须调整输出:当请求的输出具有(块号,开始)值时,您正在打印(开始,停止)值。
你能从那里拿走吗?
答案 1 :(得分:0)
使用生成器的一种可能的解决方案:
from itertools import islice, zip_longest, cycle
def chunk(it, size):
it = iter(it)
return iter(lambda: tuple(islice(it, size)), ())
def generate(l, n):
c, step = cycle(range(n)), l // n + (l % n != 0)
yield from ((next(c), v) for vals in zip_longest(*chunk(range(l), step)) for v in vals if v is not None)
l = 11
n = 3
out = [*generate(l, n)]
print(out)
打印:
[(0, 0), (1, 4), (2, 8), (0, 1), (1, 5), (2, 9), (0, 2), (1, 6), (2, 10), (0, 3), (1, 7)]
针对:
l = 9
n = 3
输出为:
[(0, 0), (1, 3), (2, 6), (0, 1), (1, 4), (2, 7), (0, 2), (1, 5), (2, 8)]