让索引返回for循环

时间:2016-03-29 15:49:08

标签: python

我试图在Python中创建一个脑力学解释器,然后想出了如何做循环,因为我遇到了问题,但现在我需要让索引重新进入以这种方式循环:

    for i in range(20):
        if i == 15:
            # Set i to 5
        print(i)

但我不需要用5代替15,而是回到索引中: 真实结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    5
    16
    17
    18
    19

预期结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    5
    6
    7
    8
    9

我怎么能这样做,所以我可以回到一个或循环?

5 个答案:

答案 0 :(得分:1)

不幸的是,每次迭代到新项目时,for循环Python中的索引器都会被分配。因此,您的一次重新分配:

if i == 15:
    i = 5

在后续迭代中获得了很多帮助

  

从Python for statement文档:

     

表达式列表评估一次;它应该产生一个可迭代的   宾语。为expression_list的结果创建一个迭代器。   然后对于由提供的每个项目执行一次该套件   迭代器,按升序索引的顺序排列。 依次是每个项目   使用分配的标准规则分配到目标列表,   然后执行套件。当物品耗尽时(即   当序列为空时立即),else子句中的套件,   如果存在,则执行,循环终止。

换句话说,对于item i,无论循环中发生什么,都会使用iterable object中提供的下一个值重新分配,在您的情况下,由range(20)

#at loop 15
[0 1 2 ... 15 16 19] #i is progressively increasing independent from what happen in the loop block
           ^ #here is i

change i to 5? you can, but only lasting for one loop!
#you print i, it shows 5, and then...

#at loop 16
[0 1 2 ... 15 16 19]
              ^ #still got reassigned at the beginning of the next loop

一种方法是创建另一个索引器 - 独立于for循环,当for循环索引器i到达15时重置该循环:

j = 0
for i in range(20):
    if i == 15:
        j = 5;
    print(j)
    j = j + 1

另一种方式,不是那么推荐,是每次i之后重新分配i >= 15(您选择每次与基本索引器重新分配进行斗争)

for i in range(20):
    if i >= 15:
        i = i - 10;
    print(i)

答案 1 :(得分:1)

简单的for…loop无法实现。

可以使用while循环和计数器执行:

i = 0
while i < 20:
    i += 1

    if i == 15:
        i = 5
    print(i)

另一个解决方案是使用协程:

def co_counter():
    i = 0
    new_i = None
    while i < 20:
        if new_i is not None:
            i = new_i - 1
        new_i = yield i
        i += 1

counter = co_counter()
for i in counter:
    if i == 15:
        counter.send(5)
    print(i)

答案 2 :(得分:1)

不可能通过语言构造

python中的for循环构造为for loop_param in iterator: block_of_statements

这意味着迭代器存在并在循环之外定义,并且参数要求迭代器为其提供下一个值。因此,无论您为参数赋值,它都将在下一次迭代时继续原始序列。

但是...... 您可以想象(并构建)接受重置条件的特殊迭代器。

class resetable_range:
    def __init__(self, val):
        self.max = val
        self.val = 0
    def __iter__(self):
        return self
    def __next__(self):
        val = self.val
        if self.val == self.max:
            raise StopIteration
        self.val += 1
        return val
    def reset(self, val):
        self.val = val

使用该对象,您可以:

l = resetable_range(5)
for i in l:
    print(i)
    if (i==3):
        l.reset(1)

你会得到:

0
1
2
3
1
2
3
1
2
3
...

答案 3 :(得分:0)

更系统地说,您可以迭代一系列范围和序列:

for r in [range(1,15),range(5,10)]:
    for i in r:
        print(i)

range的第一个参数是第一个值,第二个参数是最后一个值的后继参数。

你如何从Brainf ** k解释器中获得这些奇怪的循环?

答案 4 :(得分:-1)

for-loop的每次迭代都会从range创建的列表中提取i。 设置i=5仅对该一次迭代更改i。相反,您可以尝试附加两个范围:

for i in range(15) + range(5,10):
    print(i)