在for循环中再次迭代

3

在for循环中有没有一种方法可以再次进行迭代?例如:

for x in list:
  if(condition):
      #I'd like to grab the next iteration of the list 

如果我有[1,2,3,4],我将首先迭代1,然后在for循环中尝试推进迭代到2,以便当循环再次开始时,它将位于3。
可能吗?
我正在创建一个解析器,它读取if语句,然后希望读取行,直到遇到终止if语句的行为止。

相关:https://dev59.com/nFTTa4cB1Zd3GeqPq0ed - Denilson Sá Maia
这也与一些良好的解释相关 https://stackoverflow.com/a/46522452/6053327 - Ilja
7个回答

4
你可以像这样做:

你可以这样做:

a = [1,2,3,4,5]
b = iter(a)

try:
    while True:
        c = b.next()
        if (condition):
            c = b.next()
except StopIteration:
    pass

3
除非你需要向后兼容Python 2.5版本,否则应使用next(b)而不是b.next() - John La Rooy

3

如果您正在使用的项目是可迭代对象,则可以使用item.next()来获取下一个元素。但是,如果需要,您需要确保获取StopIteration异常。

>>> it = iter(range(5))
>>> for x in it:
...     print x
...     if x > 3:
...         print it.next()
... 
0 1 2 3 4
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
StopIteration

2
这通常是我会做的事情。但在Python3中,使用next(it)代替it.next(),因为后者变成了it.__next__() - John La Rooy

1

你需要使用continue语句。

for x in list:
  if(condition):
      continue

不太确定 OP 是否考虑过这种情况(continue 跳过 到下一项),但这很可能是他应该使用的方式 ;) +1 - user395760
不是这样的。我可能应该表述得更清楚--如果我继续,我将失去代码中所在的位置。所以,如果某些条件在if语句中为真,则我希望在该块内使用下一个迭代。如果我继续,控制权就会立即传递回循环开始处,对吧? - joslinm
@joslim:那么你就必须自己处理迭代器的丑陋内部,以便可以在迭代器上调用“next”。你不想去那里。在99.99%的情况下,你不需要这样做。重新思考你的解决方案,你可能可以在没有“continue”的情况下完成(抱歉我说得含糊,但如果我们不知道你想要做什么,很难建议替代方案)。 - user395760
啊,谢谢。我想这应该是更像samurail所说的东西——在范围之外定义变量,通知for循环我在哪里以及我正在尝试做什么。如果你读了我的编辑,我基本上只是试图解析出一个if语句的代码块。 - joslinm

1
skip = False
for x in list:
    if skip:
        skip = False
        continue
    # Do your main loop logic here
    if (condition):
        skip = True

1

你可以始终绕过for循环,直接明确使用迭代器:

iter = list.__iter__()
while True:
    x = iter.next()
    ...
    if (condition):
        x = iter.next()
    ...

当它到达列表的末尾时,这将抛出一个StopIteration异常。


1

你可以使用 while 循环代替 for 循环。 在伪代码中:

idx = 0
while idx < length(list)
    x = list[idx]
    ...
    if (condition)
        idx += 1
    ...
    idx += 1

如果你正在迭代一个列表,并且只会迭代列表,那么是的。通常,展开的for循环看起来不同(获取迭代器,在try ... except StopIteration: pass中使用while True,在结尾处获取next(iterator))。 - user395760

0
我怀疑您解析if语句的方法不是一个好办法。您也会发现无法嵌套IF语句或将它们全部放在一行上。以下是我处理的方式。
a) 将您的语言转换为BNF形式。例如,对于if语句,它可能是这样的:
ifstmnt ::=  IF &lt;condiftion> THEN &lt;trueblock> [ ELSE &lt;elseblock> ]

statment ::= ifstmnt | assignstment | whilestmnt | forstmnt 

等等

b) 确定每个点在等待什么。在IF之后,读取条件直到看到THEN。

c) 编写一个getNextToken例程,从源中读取字符,直到它有一个完整的标记。标记是可识别的单元 - IF,THEN,数字,符号。每次调用它时,它将标记返回到缓冲区。还有一个类型和值返回也很有用 - 它将节省您在许多地方转换数字。表驱动方法非常快速和灵活。

d) 然后编写许多小例程来识别每种类型的语句。一个用于IF,一个用于条件,一个用于块,一个用于语句,一个用于表达式等。这些将相互调用,并在识别语句时返回。例如,条件表达式识别器将读取布尔表达式并吃掉所有名称,AND,OR等,直到它向前看到THEN。它无法处理THEN,因此它存在,而IF识别器发现令牌是THEN,它读取下一个并调用块的识别器(可能期望BEGIN,许多语句,然后END)。

e) 每个例程都收集它所需的数据 - 条件、真块、假块,并根据需要处理它们。一个非常常见的处理方式是在内存中创建程序的树形表示。程序员定义的名称在定义时被收集到字典中,并在使用时进行检查。

f) 真正的编译器将尝试重新排列树形结构以使事情更加高效 - 但我建议这是未来的发展方向。

g) 最后的操作是遍历树形结构,以某种方式对其进行评估。如果您正在编写解释器,可以计算值并在进行过程中存储它们 - 将值存储在字典中。如果您正在编写真正的编译器,则需要为链接器生成适当的输出。那是一项重大任务。

请查看 YACC 和 LEX。它们是设计用于执行部分工作的工具,并将节省您的时间。帮助您研究的术语包括“词法分析”、“解析器”等。

祝你好运。您的项目不是易事!

另请参阅http://nedbatchelder.com/text/python-parsers.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接