31

所以我想做这样的事情:

for i in range(5):
    print(i);
    if(condition==true):
        i=i-1;

但是,无论出于何种原因,即使我正在减少 i,循环似乎也没有注意到。有没有办法重复迭代?

4

8 回答 8

40

forPython 中的循环总是向前的。如果您希望能够向后移动,则必须使用不同的机制,例如while

i = 0
while i < 5:
    print(i)
    if condition:
        i=i-1
    i += 1

甚至更好:

i = 0
while i < 5:
    print(i)
    if condition:
        do_something()
        # don't increment here, so we stay on the same value for i
    else:
        # only increment in the case where we're not "moving backwards"
        i += 1
于 2013-01-17T07:37:28.833 回答
8

Python 循环使用range的设计与 C/C++/Javafor循环不同。对于每次迭代, i 被设置为 的下一个值range(5),无论您i在两者之间做什么。

您可以改用 while 循环:

i = 0
while i<5:
    print i
    if condition:
        continue
    i+=1

但老实说:我会退后一步,再想想你原来的问题。可能您会找到更好的解决方案,因为这样的循环总是容易出错。forPython -loops 的设计不同是有原因的。

于 2013-01-17T07:36:44.473 回答
4

您对 Python 中的循环有误解。for循环并不关心你在每次迭代中做了什么i,因为它根本与循环的逻辑无关。修改i只是重新绑定一个局部变量。

您需要使用 while 循环来实现您期望的行为,其中的状态i确实会影响循环的控制流:

import random

i = 0
while i < 5:
    print(i)
    i += 1
    if random.choice([True, False]):
        i -= 1
于 2013-01-17T07:36:32.390 回答
3

range(5)创建一个包含数字的0列表4- [0, 1, 2, 3, 4]

当你在它上面运行一个 for 循环时,你正在迭代列表。这样做i-= 1只会减少列表中特定元素的,并且迭代将继续。

就像这里建议的其他答案一样,您应该使用while循环。

i= 0
while i<5:
    # do stuff
    if #condition:
        i-= 1 # or +
    i+= 1
于 2013-01-17T07:45:10.243 回答
3

重复许多其他答案,为了完整起见,您需要使用while loop.

i = 0
while i < 5:
    print(i)
    if (not condition):
       i+=1

如果你想在循环中向后移动一个迭代(而不是重复一个迭代),那么使用这个:

i = 0
while i < 5:
    print(i)
    if (condition):
        i -= 1
    else:
        i += 1

本质上,while i < 5对每次迭代进行评估,并检查是否i < 5. 因此,通过递减/不改变i,我们得到如下结果:(的值i

不变: 1->2->3-(condition satisfied)> 3 -> 4 -> 5

递减:1->2->3-(condition satisfied)>2 -> 3 -> 4 -> 5

为什么i=i-1在你的 for 循环中不让它重复迭代的原因很简单。在for循环中,i为 for 循环中的下一项赋值。i只要 Python能够将下一个项目分配给它,Python 就不会关心你对它做了什么。因此,for 循环for i in <your_iterable>:<do whatever>更接近于:

_i = 0
_length = len(<your_iterable>)
while _i < _length:
    i = _i
    _i += 1
    <do whatever>

但是,在这个类比中,您将无法访问_谓词变量 ( _i, _length)。这就是我简化逻辑的方式for loop。请注意,无论i分配给什么,它都会_i在下一次迭代时分配给,并且循环实际上并不关心是什么i

于 2013-01-17T07:54:57.183 回答
1

使用while循环:

i = 0
while i < 5:
    print(i)
    if condition:
        i -= 1
    i += 1

如前所述,这是相当单一的 Python。也许如果您发布您想要实现的目标,我们可以提供一些更好的建议。

于 2013-01-17T07:36:53.780 回答
1

in在 Python 中,可以在迭代器(循环之后的内容for..in)和它的使用者(循环内的代码)之间建立双向交换。为此,您可以send在消费者代码中使用在生成器中“注入”一个值。在您的情况下,您可以在满足条件后简单地发回当前值,并将range调用包装在一个生成器中,该生成器重复发回给它的任何内容。这里有一些代码供你玩,为了清楚起见故意冗长:

def repeateble(it):
    buf, it = None, iter(it)
    while True:
        if buf is None:
            # the buffer is empty, send them the next elem
            val = next(it)
        else:
            # there's something in the buffer
            # let's send that back
            val = buf

        # send the value and wait what they say
        back = yield val

        if back:
            # they've sent us something!
            # give them some dummy value as a result of send()
            yield None 
            # and save what they've sent in a buffer
            # for the next iteration
            buf = back

        else:
            # they haven't sent anything
            # empty the buffer
            buf = None


from random import randint

# create a repeateble generator
rng = repeateble(range(100))

for x in rng:
    print(x)

    # check "some condition"...
    if randint(1, 100) > 80:
        print('repeat:')
        # send the current value back to the generator
        # it will be returned on the next iteration
        rng.send(x)
于 2013-01-17T08:59:22.787 回答
-1

如果您正在遍历文件并根据条件拉出前面的行,则可以使用 readlines。


with open("myfile.txt", "r") as f:
    text = f.readlines()
    for row in range(0, len(text)):
        if re.search("Error", text[row]):
            print(text[row-1].strip())
于 2019-05-13T18:54:40.960 回答