Python for循环与模数

时间:2017-08-23 12:19:25

标签: python for-loop modulo

是否可以使用模运算创建一个python for循环?我在Python中有一个ringbuffer,我希望迭代startPosendPos索引之间的元素,其中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循环中直接使用模运算来实现这一点?

4 个答案:

答案 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}},添加collectionsfor索引,并自定义其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