DavidScott612
DavidScott612

Reputation: 215

Is there a better way to write this "if" boolean evaluation?

I have this small snippet of python code that I wrote. It works, but I think there should be a more streamlined method to achieve the same results. I'm just not seeing it. Any ideas?

if tx_avt >= 100: tx = 1 
elif tx_avt < 100 and tx_avt >= 50: tx = 2 
elif tx_avt < 50 and tx_avt >= 25: tx = 3
elif tx_avt < 25 and tx_avt >= 12.5: tx = 4 
else: tx = 5

Upvotes: 12

Views: 771

Answers (5)

sampson-chen
sampson-chen

Reputation: 47269

You can change it to:

if tx_avt >= 100: tx = 1 
elif tx_avt >= 50: tx = 2 
elif tx_avt >= 25: tx = 3
elif tx_avt >= 12.5: tx = 4 
else: tx = 5

Explanation:

  • If if tx_avt >= 100 is not true, then you can deduce that tx_avt < 100 must be true.
  • This eliminates the need to do the "tx_avt < 100" part in the check "elif tx_avt < 100 and tx_avt >= 50:".

The same logic cascades down & applies to the rest of the elif cases.


Related reading: Why Python Doesn't Have a Switch Statement, and its Alternatives.

Upvotes: 29

SaveTheRbtz
SaveTheRbtz

Reputation: 403

Yet another idea based on the fact that [12.5, 25, 50, 100] is a series:

MAX_BOUNDARY = 5
for tx, boundary in [(n, 25 * 2**(-n+3)) for n in range(1, MAX_BOUNDARY)]:
    if tx_avt >= boundary:
        break
else:
    tx = MAX_BOUNDARY

(This is slightly modified @StevenRumbalski version)

This could be combined with @WaiYipTung idea about bisect for O(log(n)) search if distribution of tx_avt is uniform (w.r.t. series function) and your list grows VERY large.

Otherwise you should stick to simpler and easier to understand solutions like @JoranBeasley and @SampsonChen suggested.

Upvotes: 0

Wai Yip Tung
Wai Yip Tung

Reputation: 18754

To give another idea, this can be done in a one liner using the binary search function in the bisect module.

In [106]: def index(a,x):
   .....:         return len(a) - bisect.bisect_right(a, x) + 1
   .....:

In [107]: a=[12.5,25,50,100]

In [108]: index(a,15)
Out[108]: 4

In [109]: index(a,25)
Out[109]: 3

In [110]: index(a,35)
Out[110]: 3

In [111]: index(a,50)
Out[111]: 2

In [112]: index(a,100)
Out[112]: 1

Upvotes: 3

Steven Rumbalski
Steven Rumbalski

Reputation: 45542

If your if-elif-else chain gets really long you can use this method:

for amt, tx in [(100, 1), (50, 2), (25, 3), (12.5, 4)]:
    if tx_avt >= amt:
        break
else:
    tx = 5

note: The else clause of a for loop is executed when break has not been encountered. In this case it is used to provide the default case.

Upvotes: 8

Joran Beasley
Joran Beasley

Reputation: 113940

you dont need the upper bounds on the elifs since these are resolved by the clause above them ...

elif tx_avt >= 50 : #do something
elif tx_avt >= 25 : #somthing else

on a side note in python you can do

if 3 < ab < 10 : #check if ab is between 3 and 10

Upvotes: 10

Related Questions