简体   繁体   中英

How to organize this loop in a more elegant Pythonic way

So I have a function which reduces some dataset, and returns the number of elements removed. I have to stop applying it once the number of items reduced during the function's operation is zero. Currently I've got this:

num_removed = reduction_pass(dataset)
while num_removed > 0:
    num_removed = reduction_pass(dataset)

but these two variable assignments kind of get to me. Is there a more elegant way to write this?

I assume you don't actually need the final return value, as I assume it indicates the number of removed elements, which will obviously always be 0 on the last pass.

The simple-is-better-than-complex way:

while reduction_pass(dataset) > 0: pass

The showing-off, obviously-not-serious way:

from itertools import *
list(takewhile(lambda x: x > 0, starmap(reduction_pass, repeat((dataset,)))))

You can get an iterator with

it = iter(lambda: reduction_pass(dataset), 0)

which, on every step, calls the given function and stops when 0 is retrieved.

With this iterator, you can do

for num_removed in it:
    do_whatever()

Yes, Python doesn't allow statements inside the conditions control structures. It has its pluses, and it has its minuses.

If you find the two var assignments so annoying, maybe this is better:

while True:
  num_removed = reduction_pass(dataset)
  if num_removed <= 0:
    break

Although generally I don't think you should worry about it too much.

The most obvious way to me is:

num_removed = None
while num_removed is None or num_removed > 0:
    num_removed = reduction_pass(dataset)

A while loop with a break in it is usually simplest and best, however assuming that when you said to loop while num_removed > 0 you might actually have meant num_removed != 0 , here's a fairly clean alternative:

for num_removed in iter(lambda: reduction_pass(dataset), 0):
    pass

That only makes sense of course if you actually need the intermediate values of num_removed for something inside the loop body.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM