假设我有一个长度为 953 的缓冲区 buf=b"..." 。我想使用步长 33 对其进行迭代。现在 953 不能被 33 整除,因此余数为 29。
我想迭代缓冲区,但不超过最后一次迭代的末尾。我本可以使用:
对于范围(0,954,33)中的索引:打印(索引)
问题是,如果假设步长相同,最后一个索引(924)将超出缓冲区的末尾(924+33=957)。现在我可以使用以下内容:
对于范围 (0,954,33) 中的索引: 大小=最小值(33,954-索引) ...
但是这是重复/冗长的并且感觉不Python。我觉得我这里缺少电池。
上述解决方案的问题在于,它们适用于切片/数组,而不是索引传递给函数的一般情况,在函数中,确切的值通常很重要。
我创建了一个辅助函数来避免重复。但我希望有一个范围变体可以作为标准库的一部分显式处理剩余情况
我的想法是,如果你每次迭代 i 步,也许现在将其设置为 1 步,然后在实际循环中,有条件地检查大小(例如减去当前 i 索引加上你想要从缓冲区)来查看该大小是否错误。然后,如果安全,再增加 32 步,否则增加剩余的数量。
不短,但简单,即快:
def divide(length, chunk):
blocks, remainder = divmod(length, chunk)
index = 0
for _ in range(blocks):
yield index, chunk
index += chunk
if remainder:
yield index, remainder
for index, size in divide(953, 33):
print(f"{index=} {size=}")
输出:
index=0; size=33
index=33; size=33
--- lines deleted ---
index=891; size=33
index=924; size=29