为什么 python 在 for 和 while 循环之后使用'else'?

新手上路,请多包涵

我了解此构造的工作原理:

 for i in range(10):
    print(i)

    if i == 9:
        print("Too big - I'm giving up!")
        break
else:
    print("Completed successfully")

但我不明白为什么 else 在这里用作关键字,因为它表明有问题的代码仅在 for 块未完成时运行,这与什么相反确实如此!无论我怎么想,我的大脑都无法从 for 语句无缝地前进到 else 块。对我来说, continuecontinuewith 会更有意义(我正在努力训练自己这样阅读)。

我想知道 Python 编码人员如何在他们的脑海中阅读这个结构(或者大声朗读,如果你愿意的话)。也许我遗漏了一些可以使此类代码块更容易破译的东西?


这个问题是关于 底层设计决策 的,即 为什么能够编写这段代码是有用 的。有关 语法含义 的具体问题,另请参阅 Python while 语句中的 Else 子句

原文由 Kent Boogaart 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 279
2 个回答

即使对于经验丰富的 Python 编码人员来说,它也是一种奇怪的结构。当与 for 循环结合使用时,它基本上意味着“在可迭代对象中找到一些项目,否则如果没有找到就做……”。如:

 found_obj = None
for obj in objects:
    if obj.key == search_key:
        found_obj = obj
        break
else:
    print('No object found.')

但是无论何时你看到这个结构,一个更好的选择是将搜索封装在一个函数中:

 def find_obj(search_key):
    for obj in objects:
        if obj.key == search_key:
            return obj

或者使用列表理解:

 matching_objs = [o for o in objects if o.key == search_key]
if matching_objs:
    print('Found {}'.format(matching_objs[0]))
else:
    print('No object found.')

它在语义上不等同于其他两个版本,但在非性能关键代码中工作得很好,在这些代码中无论您是否迭代整个列表都无关紧要。其他人可能不同意,但我个人会避免在生产代码中使用 for-else 或 while-else 块。

另见 [Python-ideas] for…else 线程总结

原文由 Björn Lindqvist 发布,翻译遵循 CC BY-SA 4.0 许可协议

一个常见的构造是运行一个循环,直到找到某些东西,然后跳出循环。问题是,如果我跳出循环或循环结束,我需要确定发生了哪种情况。一种方法是创建一个标志或存储变量,让我进行第二次测试以查看循环是如何退出的。

例如,假设我需要搜索列表并处理每个项目,直到找到标志项,然后停止处理。如果缺少标志项,则需要引发异常。

使用 Python forelse 构造你有

for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

将此与不使用此语法糖的方法进行比较:

 flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)

if not flagfound:
    raise ValueError("List argument missing terminal flag.")

在第一种情况下, raise 与它一起使用的 for 循环紧密绑定。在第二种情况下,绑定不那么牢固,维护期间可能会引入错误。

原文由 Lance Helsten 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题