Python - 如何重新启动for循环,类似于while循环中的“continue”?

15

基本上,我需要一种方法,在满足某个条件时,返回到 for 循环的开头并重新开始整个迭代过程。

我要做的是这样的:

    for index, item in enumerate(list2):
    if item == '||' and list2[index-1] == '||':
        del list2[index]
        *<some action that resarts the whole process>*

这样,如果 ['berry','||','||','||','pancake] 在列表中,我最终得到的将是:

['berry','||','pancake']。

谢谢!


你是在询问嵌套循环吗?while something: for ...?如果是的话,有什么复杂的地方吗?请发布一个代码示例以展示你正在做什么。 - S.Lott
你能提供一些示例代码,这样我们就可以弄清楚你的问题了。 "continue" 对于 "for" 和 "while" 循环都适用。看起来你想要不同的东西。 - Aaron D
5
对于 while 循环,continue 语句仅仅跳过循环体中的剩余部分,与 for 循环的作用相同。请尝试重新表述你的问题,描述你想要实现什么,而不是如何实现它。 - Geoff Reedy
是啊,我真的很好奇你为什么要这样做。也许如果你从整体上考虑问题,会有更好的解决方案。 - David Z
谢谢大家。我已经编辑了原帖并附上了一个代码示例,解释了我想要做的事情! - Georgina
虽然THC4k没有回答这个问题,但它是解决你原始问题的好方法。如果你坚持要从列表中删除项目,最好只使用一个while循环并自己管理索引。 - John La Rooy
8个回答

43

我不确定你所说的“重新启动”是什么意思。你是想从头开始迭代,还是仅跳过当前迭代?

如果是后者,那么for循环和while循环一样支持continue

for i in xrange(10):
  if i == 5:
    continue
  print i

上面的代码将打印从0到9的数字,但不包括5。

如果你想要从for循环重新开始,除了通过手动方式,例如在while循环中包装它之外,没有其他方法:

should_restart = True
while should_restart:
  should_restart = False
  for i in xrange(10):
    print i
    if i == 5:
      should_restart = True
      break

上面的代码将会打印从0到5的数字,然后再次从0开始循环,一直这样无限循环下去(我知道这并不是一个很好的例子)。


非常感谢!第二个解决方案真是太棒了。 - Georgina
没问题。还可以看一下Nathon的答案,它使用了forelse子句,更加简洁明了。 - Liquid_Fire
1
哈哈,第二个例子闻起来像是C++的味道太浓了。 - machine yearning

26
while True:
    for i in xrange(10):
        if condition(i):
            break
    else:
        break

这会做你想要的事情。为什么你想这样做是另外一回事。也许你应该检查一下你的代码,确保你没有错过一个明显和更容易的方法来完成它。


3
作为阐明(因为 for: ... else: 可能有点令人困惑,并且在两个嵌套循环中也有 break ):如果条件为真,则会跳出 for 循环,这意味着它跳过了该循环的 else 部分,这意味着它回到了 while 循环的顶部。如果条件始终为假,则完成 for 循环,进入 else 部分,然后从 while 循环中 break - Vivian

5

重新启动整个过程的某些操作

算法的一种不好的思考方式。

你只是在过滤,即删除重复项。

而且 - 在Python中 - 你最喜欢制作副本,而不是尝试使用del。一般来说,很少有需要使用del的情况。

def unique( some_list ):
    list_iter= iter(some_list)
    prev= list_iter.next()
    for item in list_iter:
        if item != prev:
            yield prev
            prev= item
    yield prev

list( unique( ['berry','||','||','||','pancake'] ) )

他正在删除相邻的重复项,明确一下。看起来这就是你的方法所做的,但这并不是通常所说的“唯一”的含义。 - David M.
@David M.:尽管如此,这是一种“消极”的评论。“独特不合适”。好的。你有什么建议吗?你能提出一个“积极”的意见吗? - S.Lott
当然,如果你需要那种宠爱的话。(值得一提的是,我已经为你的答案点赞了;我不是想打击你,只是不希望原帖作者感到困惑。) itertools 的配方称其为 unique_justseen,也许 unique_adjacent 更好些。 - David M.
@David M:“试图打击你”什么?你指出了可能的错误。为什么不采取下一个逻辑步骤并提出建议呢?这不是“纵容”,而是提供价值的方法。说某件事“不是通常意义上的”价值很小。改进答案会增加更多的价值。指出错误并不能增加太多价值。我不是要求纵容。我要求你尽可能地创造价值。你一定有一些见解。分享一下吧。 - S.Lott
2
抱歉,我误解了你的评论。可能是因为我周围都是人力资源的缘故。 - David M.

4
不可避免的是itertools版本,因为它刚刚出现在我的脑海中。
from itertools import groupby

def uniq(seq):
    for key, items in groupby(seq):
        yield key

print list(uniq(['berry','||','||','||','pancake'])) # ['berry','||', 'pancake']
# or simply:
print [key for key, items in groupby(['berry','||','||','||','pancake'])]

+1,我只会返回一个生成器表达式 - John La Rooy

3

Continue语句适用于任何循环。


但是我正在寻找一种重新启动for循环的方法... 控制返回到最初状态。 - Georgina
这是一个很好的参考链接:http://en.wikibooks.org/wiki/Python_Programming/Flow_control#Breaking.2C_continuing_and_the_else_clause_of_loops - Aaron D

3

continue 相关的语法也适用于 for 循环。

>>> for i in range(3):
...     print 'Before', i
...     if i == 1:
...             continue
...     print 'After', i
... 
Before 0
After 0
Before 1
# After 1 is missing
Before 2
After 2

谢谢,这很有用!但我正在寻找一种重新启动整个for循环的方法...控制回到最初的状态。 - Georgina

1

正如您所看到的,回答您的问题会导致一些相当复杂的代码。通常可以找到更好的方法,这就是为什么这样的结构不会内置于语言中的原因。

如果您不熟悉使用itertools,请考虑改用此循环。它不仅比您重新启动的for循环更易于跟踪,而且还更有效率,因为它不会浪费时间重新检查已经被忽略的项目。

L = ['berry','||','||','||','pancake']
idx=1
while idx<len(L):
    if L[idx-1]==L[idx]:
        del L[idx]
    else:
        idx+=1

0
def remove_adjacent(nums):
     return [a for a,b in zip(nums, nums[1:]+[not nums[-1]]) if a != b]

example = ['berry','||','||','||','pancake']

example = remove_adjacent(example)
print example
""" Output:
['berry', '||', 'pancake']
"""

顺便提一下,这是从列表中删除相邻重复元素的重复。


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