Hadij
Hadij

Reputation: 4640

Best way to write "nested if" for different ranges

I am going to write down this pseudocode in python:

if (i < .1):
   doX()
elif (i < .3):
   doY()
elif (i < .5):
    doZ()
.
.
else:
    doW()

The range of numbers may be 20, and each float number which shapes the constraints is read from a list. For the above example (shorter version), it is the list:

[0.1, 0.3, 0.5, 1]

Is there any pythonic way or a function which can do different functions for different associated ranges?

Upvotes: 0

Views: 863

Answers (4)

Ohad Rubin
Ohad Rubin

Reputation: 480

from bisect import *
a=[0.1, 0.3, 0.5, 1]
b=["a","b","c","d"]
print b[bisect_left(a,0.2)]

Upvotes: 3

Laurent H.
Laurent H.

Reputation: 6526

I suggest you to create the following dictionary with numbers as keys and functions as values:

d = {0.1:doX, 0.3:doY, 0.5:doZ, 1:doW}

Then use the following code:

for n,(k,f) in enumerate(sorted(d.items())):
    if (i < k) or (n == (len(d) - 1)):
        f()
        break

Upvotes: 1

ivan7707
ivan7707

Reputation: 1156

def a():
    print('a returned')

def b():
    print('b returned')

def c():
    print('c returned')

funcs = [a, b, c]

def sample_func(x, funcs=None):
    if x < 0:
        return None    
    thresholds = [.40, .60]

    for i, threshold in enumerate(thresholds):
        if x <= threshold:
            return funcs[i]()
    return funcs[len(thresholds)]()

sample_func(.1, funcs)

returns

a returned

sample_func(.65, funcs)

returns

c returned

Upvotes: 1

user2988908
user2988908

Reputation:

Here's an answer that you should not use:

doX = lambda x: x + 1
doY = lambda x: x + 10
doZ = lambda x: x + 100
ranges    = [0.1, 0.3, 0.5, 1]
functions = [doX, doY, doZ]
answer = lambda x: [func(x) for (low, high), func in zip(zip(ranges[:-1],ranges[1:]), function) if low <= x < high][0]

The point is, that getting to fancy with it becomes unreadable. The if..elif..else is the "one-- and preferably only one --obvious way to do it.".

Upvotes: 1

Related Questions