I often have to randomly generate stuff with certain constraints. In many cases, it's quicker to ignore the constraints in generation, check if they are met afterwards and redo the process otherwise. Lacking a do keyword, I usually write
r = random_stuff()
while not meets_condition(r):
r = random_stuff()
That's a bit ugly, as I have the same line of code twice. What I'd really like to have is a construct like
r = random_stuff() until meets_condition(r)
similar to the ternary operator introduced in 2.5:
a = b if condition else c
Just that here condition is evaluated before the left-hand side of the statement is executed. Does anybody have a suggestion for a design pattern (should work in Python 2.7) that remedies the while-constructs intrinsic unpythonic ugliness?
while True:
r = random_stuff()
if meets_condition(r):
break
or
condition = True
while condition:
r = random_stuff()
condition = not meets_condition(r)
Your idea is not bad - but not with the new keyword until, but rather like
a = (<expression> while <condition>)
extending the idea of generator expressions.
As they don't exist, it won't help you.
But what you can use, is the iter function with the sentinel.
dummy_sentinel = object()
for r in iter(random_stuff, dummy_sentinel):
if meets_condition(r): break
If you can be sure about your random_stuff() returning only a certain kind of values, such as numbers, strings, etc., you can take some other value as sentinel. Especially, when None never can occur, take this, in order to have a never-ending generator.
for r in iter(random_stuff, None):
if meets_condition(r): break
Then random_stuff() gets called until it meets the condition.
Even better might be
r = next(r for r in iter(random_stuff, None) if meets_condition(r))
which gives you the first matching one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With