gpt4 book ai didi

带模数的 Python for 循环

转载 作者:行者123 更新时间:2023-11-28 20:36:02 26 4
gpt4 key购买 nike

是否可以使用模运算创建 python for 循环?我在 Python 中有一个环形缓冲区,我想迭代 startPosendPos 索引之间的元素,其中 startPos 的值可以大于 结束位置。在其他编程语言中,我会直观地使用模运算符来实现它:

int startPos = 6;
int endPos = 2;
int ringBufferSize = 8;
for(int i = startPos, i != endPos, i = (i+1) % ringBufferSize) {
print buffer.getElementAt(i);
}

有没有办法在 Python 中轻松做到这一点?我只找到了

for i in list:
print buffer[i]

语法但没有为我的问题提供等效的解决方案。

我的下一个方法是在迭代存储在列表中的索引之前提前创建列表。但是,有没有一种方法可以像在其他编程语言中一样,直接在 for 循环中使用取模运算,以单行方式完成此操作?

最佳答案

你有一些方法可以做到这一点:

正如您在“其他编程语言”(即 C 派生语法)中所做的那样,您基本上必须以 while 形式编写它们的 for 循环 - 然后您意识到 C 的 for 只是尽管如此,while:

start_pos = 6
end_pos = 2
ring_buffer_size = 8
i = start_pos
while True:
i = (i + 1) % ring_buffer_size
if i <= end_pos:
break
# your code here

现在,对于 for 语句,Python 只有所谓的“for each”——它总是遍历一个可迭代对象或序列。所以你可以创建一个迭代器来产生你的值 -

def ring(start, end, buffer_size, increment=1):
i = start
while i != end:
yield i
i += 1
i %= buffer_size

for slot in ring(6, 2, 8):
# your code here

请注意,虽然第二种形式“更大”,但它确实抽象出您的循环缓冲区逻辑,避免硬代码值与它们的含义混淆,而您不需要查看它们 - 即,在 for body 本身。

请注意,Python 中 for 的实际想法是迭代 buffer 内容本身,而不是索引将导致其内容。
因此,Python 标准库已经包含一个现成的循环缓冲区对象,它的索引总是规范化为 0 和 (len - 1) -只需从 collections 模块导入 deque

如果您想要一个循环缓冲区,其开始和结束索引不断变化,taht 将环绕并在 for 语句中自动工作,这也相对容易实现 - 如果您不需要完整的功能,只需子类 list,添加 startend 索引,并对其 __iter__ 方法进行自定义实现:

class Circular(list):

def __init__(self, content, start, end):
super(Circular, self).__init__( content)
self.start = start
self.end = end

def __iter__(self):
for i in range(self.start, self.start + len(self)):
if i % len(self) == self.end: break
yield self[i % len(self)]

现在您可以在您的代码中使用这个自定义容器:

In [22]: mylist = Circular(range(8), 6 , 2)

In [23]: for i in mylist:
...: print(i)
...:
6
7
0
1

关于带模数的 Python for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45839541/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com