pythonpython-3.xloopslogic

How can I run a loop forever until a termination condition or for a fixed number of iterations?


I have a program that runs an operation either a fixed number of times, or "forever" until some condition is reached. The implementation was fine, but I was having trouble getting a code structure I was happy with.

My initial logic boiled down to:

max_iterations = 5 # Either an integer or None (the number actually comes from user input)
stop_flag = False

i = 0
while not stop_flag:
    do_some_operation(i)
    i += 1
    stop_flag = (i == max_iterations) or test_some_stop_condition()

But I wasn't very happy with this, I don't like that there's both an i variable and a stop flag.

The stop flag can be eliminated by moving the logic to the while:

i = 0
while not ((i == max_iterations) or test_some_stop_condition()):
    do_some_operation(i)
    i += 1

but this seems even less readable to me. That conditional is not particularly understandable now it's moved to the while.

So, I used itertools.count to do the iteration:

import itertools
max_iterations = 5 # Either an integer or None (the number actually comes from user input)
for i in itertools.count():
    do_some_operation(i)
    if (i == max_iterations) or test_some_stop_condition():
        break

I'm not very happy with this either, but I think it's reasonably clean and readable. Ideally I think the termination condition should be entirely in the for or while, leaving the body of the loop entirely for the actual work, but I can't think of a way to do it cleanly.

Is there a better solution?

Some notes:

(This question might be better suited to https://codereview.stackexchange.com/, I'm honestly not sure...)


Solution

  • max_iterations could be handled with

    for i in islice(count(), max_iterations):
    

    or

    for i in count() if max_iterations is None else range(max_iterations):
    

    or if int values are always positive:

    for i in range(max_iterations) if max_iterations else count():