只有当for循环没有开始迭代(使用生成器)时,Python才会执行代码?

2rs*_*2ts 5 python generator python-2.7

如果迭代完成但没有被中断,则/ 子句中的else块被执行,所以我读了.forelsebreak

是否有一种语言结构可以让我写一些只有在for循环没有开始迭代时执行的东西?如果我正在使用tuplelist,我会做这样的事情:

if seq:
    for x in seq:
         # something
else:
    # something else
Run Code Online (Sandbox Code Playgroud)

但是当我使用生成器时,我没有得到我想要的行为:

>>> g = (x for x in range(2))
>>> for x in g:
...     print x
... else:
...     print "done"
... 
0
1
done    # I don't want "done" here
>>> g = (x for x in range(2) if x > 1)
>>> if g:
...     for x in g:
...         print x
... else:
...     print "done"
... 
>>>     # I was expecting "done" here
Run Code Online (Sandbox Code Playgroud)

我怎么能这样做而不用耗尽从发电机创建a tuple或a list,同时还使用for循环?我可以next()while循环中使用并尝试捕获StopIteration,但我想看看是否有一个很好的方法来实现它for.

Pet*_*per 8

我想不出比更新 for 循环内的布尔值更好的方法。

any_results = False
for x in g:
    any_results = True
    print x
if not any_results:
    print 'Done'
Run Code Online (Sandbox Code Playgroud)

  • 是的,我通常会这样做;我只是想知道是否有一个控制结构或其他语言结构可以简洁地完成此操作。 (2认同)

glg*_*lgl 5

n = -1
for n, i in enumerate(it):
    do_stuff()
if n < 0:
    print 'Done'
Run Code Online (Sandbox Code Playgroud)


sha*_*359 5

我发现这个解决方案更好。检查此链接以获取更多信息(http://python-notes.curiousefficiency.org/en/latest/python_concepts/break_else.html)。

您可以使用自定义哨兵: x = no_data = object()

x = no_data = object()
for x in data:
    .......
if x is no_data:
    print "Loop did not run"
Run Code Online (Sandbox Code Playgroud)

object() 返回一个无特征的对象,它是所有类的基础。

检查两个对象是否相同(x 是 no_data)。如果它们保持相同,则意味着控件从未进入 for 循环。