Reputation: 44674
Maybe this question has been asked before, but I couldn't find it. I am trying to implement something that determines what range a given value is in. In this example, x may be any real number.
def f(x):
if x < 0.1:
do_something_1()
elif 0.1 <= x < 1:
do_something_2()
elif 1 <= x < 10:
do_something_3()
elif x >= 10:
do_something_4()
...you get the idea.
I've seen plenty of examples of dictionaries replacing switch statements in Python, but I've always understood dictionaries as indexing discrete values.
I find it hard to believe that the if-elif-else chain is the best solution in this situation. Does anyone know of a better one?
Upvotes: 2
Views: 307
Reputation: 24788
Here's another way to do it, using a dict and for loop:
ranges_dict = {
0.1: do_something1,
1.0: do_something2,
10.0: do_something3,
}
for range_val, do_function in sorted(ranges_dict.items()):
if x < range_val:
do_function()
break
else:
do_something_else()
Upvotes: 1
Reputation: 602735
An easy way to improve this is not to repeat the lower bounds. Your code is equivalent to
if x < 0.1:
do_something_1()
elif x < 1:
do_something_2()
elif x < 10:
do_something_3()
else:
do_something_4()
If there are really many values, you might want to bisect
instead, but with only four options, the above code is probably the best solutuion, at least in terms of readability and speed.
Upvotes: 12
Reputation: 78660
Use the bisect package to find the index where the value lies, and then call the appropriate function. In your example:
import bisect
def f(x):
funcs = [do_something_1, do_something_2, do_something_3, do_something_4]
funcs[bisect.bisect_left([.1, 1, 10], x)]()
Upvotes: 9