【问题标题】:Stopping an iteration without using `break` in Python 3在 Python 3 中不使用“break”就停止迭代
【发布时间】:2015-01-20 01:05:25
【问题描述】:

例如,可以在没有break(并且没有continuereturn)的情况下重写此代码吗?

import logging

for i, x in enumerate(x):
    logging.info("Processing `x` n.%s...", i)
    y = do_something(x)
    if y == A:
        logging.info("Doing something else...")
        do_something_else(x)
    elif y == B:
        logging.info("Done.")
        break

编辑:由于有些人批评在循环中使用 breakcontinue,我想知道 Python 是否允许在没有它们的情况下编写 for 循环。我会说 Python 不允许这样做(也许它会违反“一种方法”的规则)。

EDIT2:评论者让我注意到可以使用return,但这也不是解决方案。

【问题讨论】:

  • 是的,但你为什么要这个?
  • 您是否需要一种在不中断循环控制流的情况下重写代码的方法?我认为背后的原因将大大提高您获得答案的质量。
  • 我已添加说明。
  • 偶尔使用breakcontinue 并不是坏事。但是,如果您发现自己在每个循环中都编写它们,您可能需要重新评估您的设计。
  • 埃琳娜,你的代码很好。忘掉那些“有些人”会试图给你穿上紧身衣的废话吧。你的问题似乎相当于“一个人可以在不打破循环的情况下打破一个循环”。如果默认的隐式行为是继续循环,则“否”。如果您实际上是在问“我可以在辅助迭代器中隐藏中断,那么“是”。

标签: python python-3.x foreach iteration


【解决方案1】:

你总是可以使用一个函数并从它返回:

import logging

def func():
    for i, x in enumerate(x):
        logging.info("Processing `x` n.%s...", i)
        y = do_something(x)
        if y == A:
            logging.info("Doing something else...")
            do_something_else(x)
        elif y == B:
            logging.info("Done.")
            return # Exit the function and stop the loop in the process.
func()

虽然在我看来使用break 更优雅,因为它让你的意图更清晰。

【讨论】:

    【解决方案2】:

    您可以使用布尔值来检查您是否已完成。它仍然会迭代循环的其余部分,但不执行代码。完成后,它将继续前进而不会中断。下面的示例伪代码。

    doneLogging = False
    for i, x in enumerate(x):
        if not doneLogging:
            logging.info("Processing `x` n.%s...", i)
            y = do_something(x)
            if y == A:
                logging.info("Doing something else...")
                do_something_else(x)
            elif y == B:
                logging.info("Done.")
                doneLogging = True
    

    【讨论】:

    • 把它和itertools.takewhile()结合起来,你就有了一个非常棒的解决方案。
    • @marsh:我认为doneLogging = False 应该在循环之外。一个奇怪的解决方案,但它确实有效。
    • @Kevin:我认为将itertools.takewhile() 与辅助功能一起使用是唯一可以接受的答案,谢谢。
    • takewhile 使用中断来停止循环。
    【解决方案3】:

    你也可以使用sys.exit()

    import logging
    import sys
    
    for i, x in enumerate(x):
        logging.info("Processing `x` n.%s...", i)
        y = do_something(x)
        if y == A:
            logging.info("Doing something else...")
            do_something_else(x)
        elif y == B:
            logging.info("Done.")
            sys.exit(0)
    

    【讨论】:

      【解决方案4】:

      breakcontinue 关键字仅在循环内有意义,在其他地方它们是错误的。

      for grooble in spastic():
          if hasattr(grooble, '_done_'):
              # no need for futher processing of this element
              continue
          elif grooble is TheWinner:
              # we have a winner!  we're done!
              break
          else:
              # process this grooble's moves
              ...
      

      任何说不应该使用breakcontinue 的人都不是在教好的Python。

      【讨论】:

        猜你喜欢
        • 2015-12-15
        • 2020-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-05
        • 2011-09-11
        • 2022-01-11
        相关资源
        最近更新 更多