是否可以使用模运算创建一个python for循环?我在Python中有一个ringbuffer,我希望迭代startPos
和endPos
索引之间的元素,其中startPos
的值可能大于endPos
。在其他编程语言中,我会直观地使用模运算符来实现它:
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循环中直接使用模运算来实现这一点?
答案 0 :(得分:3)
For循环可以采用任何迭代。因此,您可以创建自己的工作并将其放入for循环中。例如:
for i in [i % ring_buffer for i in range(start_pos, end_pos)]:
# Do stuff...
或者,直接创建一个iterable:
for i in (i % ring_buffer for i in range(start_pos, end_pos)):
# Do stuff...
有关何时可能希望直接为此目的创建迭代器的详细信息,请参阅the docs。
答案 1 :(得分:3)
你有一些方法可以做到这一点:
正如您在“其他编程语言”(即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
语句,Python只有“for each”所谓的 - 它总是遍历可迭代或序列。因此,您可以创建一个可以产生值的迭代 -
for
请注意,虽然第二种形式是“更大”,但它确实抽象出了循环缓冲逻辑,避免硬代码值与它们的含义混合在一起,而不需要查看它们 - 也就是说,在{ {1}}身体本身。
请注意,Python中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
的实际想法是迭代缓冲区内容本身,而不是索引将导致其内容的内容。
因此,Python标准库包含一个现成的循环缓冲区对象,它总是将其索引标准化为0和(len - 1) -
只需从for
模块中导入for
。
如果你想要一个带有改变开始和结束索引的循环缓冲区,taht会在deque
语句中自动回滚并运行,这也相对容易 - 如果你不需要完整的功能,只需要子类{{ 1}},添加collections
和for
索引,并自定义其list
方法的实现:
start
现在您可以在代码中使用此自定义容器:
end
答案 2 :(得分:1)
使用范围
for i in range(0,len(a)):
#code
i=i%x
答案 3 :(得分:-1)
我相信你应该能够使用while
代替for
循环。只要你想每次将i
增加1,然后计算mod,这就应该有效。
尝试:
i = startPos
while (i <= endPos and i == (i+1) % ringBufferSize) :
print buffer.getElementAt(x)
i = i+1