在 Python 中迭代多个起止值

Posted

技术标签:

【中文标题】在 Python 中迭代多个起止值【英文标题】:Iterate Over Multiple Start-Stop Values in Python 【发布时间】:2019-12-13 18:12:07 【问题描述】:

假设我有一个数字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)

在这种情况下,第一个块 (chunk 0) 从 0 变为 4(5 个元素),下一个块 (chunk 1) 从 4 变为 8(5 个元素),最后一个块 ( chunk 2) 稍微小一些,从 8 到 11(4 个元素)。当然,ln 的值可能会有所不同,但两个值始终为正整数,n 始终小于 l

我需要做的是生成一个列表,该列表将以循环方式遍历每个块,并将一些块信息附加到列表中。该列表应包含块编号的元组(即012)和该块中的下一个可用起始值(直到该块在stop 值的控制下耗尽) .因此,输出列表将是:

[(0,0), (1,4), (2,8), (0,1), (1,5), (2,9), (0,2), (1,6), (2,10), (0,3), (1,7)]

请注意,最后一个块比前两个块有一个最后一个元素。无论解决方案是什么,它都需要适用于任何ln(只要这两个值都是正整数并且n 总是小于l)。为简单起见,您可以假设 l 将小于 100,000,000。

生成此列表的最佳方法是什么?

【问题讨论】:

最后一个分组不应该存在:您已经涵盖了第一组中的 4-8 个分块。 哦,你是对的!列表中应该只有 11 个元素。现已更新 【参考方案1】:

对问题的两个级别使用两个循环。外部循环通过range(step) 中的所有数字运行起点。从那里,使用该值作为您已经编写的内部循环的起点。请注意,您必须调整输出:当您请求的输出具有 (chunk#, start) 值时,您正在打印 (start, stop) 值。

你能从那里拿走吗?

【讨论】:

我想我必须添加一些停止条件才能打破两个 for 循环?我认为必须有某种方法可以通过 itertools 完成此操作 您可以通过简单的for 循环获得停止条件。一旦你对这些循环进行了编码(enumerate 会给你块#),将它们折叠成一个列表理解。还可以查找“分块列表”以检查您的代数;你可以窃取他们的一些算术。【参考方案2】:

一种可能的解决方案,使用生成器:

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

【讨论】:

对不起,我在输出上犯了一个错误。请在 OP 中查看正确(更新)的输出 不,l=9 时应该只有 9 个元素。你的答案有 10 个元素 我会修正step 的计算。不仅会提供更好的结果,而且还允许更简单的代码。 @StefanPochmann 我用itertools完全重写了它,现在它生成了均匀间隔的块。 @slaw 用 itertools 修改了我的答案,现在应该会产生更好的结果。

以上是关于在 Python 中迭代多个起止值的主要内容,如果未能解决你的问题,请参考以下文章

从python 3.5中的函数返回多个值[重复]

Python:替换多个 for 循环、多个迭代器

python学习第十三天 迭代器 生成器

如何从 Python 中的文件/流中懒惰地读取多个 JSON 值?

通过 SQL 中的多个数据库在 Python 中迭代循环

python_如何在一个for循环中迭代多个可迭代对象?