I have a functions in Python which has a series of if statements.
def some_func():
if condition_1:
return result_1
if condition_2:
return result_2
... #other if statements
But I want that the order of these if statements is changed every time I call the function.
Like if I call the function there can be a case when condition_1
and condition_2
both are true but since condition_1
is checked first thus I will get result_1
but I want that when I call the function second time some other random condition to be checked. (since I have only five if statements in the function therefore any one of the five conditions).
So is there any way to do this like storing the conditions in a list or something.
Any help will be appreciated.
Santiago Trujillo
You can create list of condition
and result
then shuffle
them like below:
import random
def some_func(x):
lst_condition_result = [((x>1), True), ((x>2), False)]
random.shuffle(lst_condition_result)
for condition, result in lst_condition_result:
if condition:
return result
Output:
>>> some_func(20)
True
>>> some_func(20)
False
>>> some_func(20)
False
If you want to shuffle at run-time, then put your conditions and results as functions in a list of functions (once) and shuffle it (each time). Then evaluate those functions in that shuffled order until you get a non-falsy value (assuming the return
statements always return a non-falsy value).
At the time of writing you did not provide a concrete example, so I'll work with this one:
def odd_or_multipleof3(n):
if n % 2:
return "odd"
if n % 3 == 0:
return "multiple of 3"
return "neither"
Here odd_or_multipleof3(9)
will return "odd", but when the if
blocks are swapped, it would return "multiple of 3". To let the evaluation of blocks happen in a random order, so that you could get either of these return values, you could do this:
from random import shuffle
funcs = [
lambda n: "odd" if n % 2 else None,
lambda n: "multiple of 3" if n % 3 == 0 else None
]
def odd_or_multipleof3(n):
shuffle(funcs)
return any((result := func(n)) for func in funcs) and result
print(odd_or_multipleof3(9))
This way of working will guarantee that conditions are only evaluated for as long as they don't return a truthy value, not more.
This one only evaluates as much as necessary, i.e., just as much as literally shuffled if-statements would:
def some_func():
conditions_and_results = [
(lambda: condition_1, lambda: result_1),
(lambda: condition_2, lambda: result_2),
...
]
random.shuffle(conditions_and_results)
for condition, result in conditions_and_results:
if condition():
return result()
Or more efficiently (at least for large lists), reusing the same list every time and only shuffling as much as needed:
ifs = [
(lambda: condition_1, lambda: result_1),
(lambda: condition_2, lambda: result_2),
...
]
def some_func():
for i, if_i in enumerate(ifs):
j = random.randrange(i, len(ifs))
condition, result = ifs[i] = ifs[j]
ifs[j] = if_i
if condition():
return result()
Demo (Try it online!):
import random
ifs = [
(lambda: x > 0, lambda: '> 0'),
(lambda: x > 1, lambda: '> 1'),
(lambda: x > 2, lambda: '> 2'),
(lambda: x > 3, lambda: '> 3'),
]
def some_func():
for i, if_i in enumerate(ifs):
j = random.randrange(i, len(ifs))
condition, result = ifs[i] = ifs[j]
ifs[j] = if_i
if condition():
return result()
x = 2
print([some_func() for _ in range(10)])
Sample output:
['> 1', '> 0', '> 1', '> 0', '> 0', '> 0', '> 0', '> 1', '> 0', '> 0']