Stopping an iteration without using `break` in Pyt

2020-04-10 06:38发布

问题:

For example, can this code be rewritten without break (and without continue or return)?

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

EDIT: Since some people criticize the use of break and continue inside loops, I was wondering whether Python allowed to write for loops without them. I would say that Python doesn't allow this (and maybe it would go against the "one way to do it" rule).

EDIT2: Commenters have made me notice that return could be used instead, but that would not be a solution, either.

回答1:

You could always use a function and return from it:

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()

Although using break is more elegant in my opinion because it makes your intent clearer.



回答2:

You could use a boolean value to check if you are done. It will still iterate the rest of the loop but not execute the code. When it is done it will continue on its way without a break. Example Pseudo code below.

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


回答3:

You can also use 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:

The break and continue keywords only have meaning inside a loop, elsewhere they are an error.

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
        ...

Anyone who says break and continue should not be used is not teaching good Python.