Reputation: 541
I am reading Grokking Algorithms, which seems to be a highly recommended book. I am looking at the first algorithm for "binary search" and the guy uses two "ifs" instead of a "if" and "elif". Would using two "ifs" be better or faster?
def binary_search(list, item):
low = 0
high = len(list) - 1
while low <= high:
mid = (low + high)
guess = list[mid]
if guess == item:
return mid
if guess > item:
high = mid - 1
else:
low = mid + 1
return None
my_list = [1,3,5,7,9]
Upvotes: 4
Views: 3138
Reputation: 8168
You use multiple ifs, when you want to accomplish different tasks that are independent of each other. And the execution of one of the tasks doesn't effect the execution of others.
Let's look at an example:
if primeMember:
makeDeliveryFree()
if validDiscountCoupon:
giveDiscount(couponCode)
if customersBirthday:
giveBirthdayDiscount()
So, in the above example we have different tasks that we want to perform under different conditions and the tasks are independent of each other. Making the delivery free doesn't effect the discount in any manner.
With multiple ifs, it could be possible that the statements within all the if
s get executed and on the other hand it could also be possible that none of the statements within the if
s get executed.
On the other hand we would use an if
, elif
, else
chain, when we want to accomplish a particular task but we want to accomplish that differently under different conditions.
Let's look at an example:
if hasBalanceInWallet:
setPaymentMode("wallet")
elif hasCreditCardSaved:
setPaymentMode("credit-card")
else
showPaymentModeSelectorDialog()
So, in the above example the task that we're trying to accomplish is that of setting the mode of payment and we need to set it differently under different scenarios but we only want to set it once (i.e. we want only one of the branches to run).
Upvotes: 2
Reputation: 857
As other answers mentioned, an elif
is not necessary after an if
that does a return
. But they didn't cover the performance impact. I thought it would be interesting to test.
Turns out, it can be a tad faster to use if/elif/else
instead of separate if
's.
from timeit import timeit
import random
def count_items_ifelifelse(items, threshold):
below, on, above = 0, 0, 0
for item in items:
if item > threshold:
above += 1
elif item < threshold:
below += 1
else:
on += 1
return below, on, above
def count_items_ififif(items, threshold):
below, on, above = 0, 0, 0
for item in items:
if item > threshold:
above += 1
if item < threshold:
below += 1
if item == threshold:
on += 1
return below, on, above
def generate_items_and_threshold(count=100_000):
"""List of reproducible random numbers to test with. Set threshold at half"""
items = list(range(count))
random.Random(123).shuffle(items)
threshold = count // 2
return items, threshold
def run_test():
t1 = timeit(
"count_items_ifelifelse(i, t)",
setup="from __main__ import count_items_ifelifelse, generate_items_and_threshold; i, t = generate_items_and_threshold()",
number=1000,
)
print("count_items_ifelifelse: {:.2f}".format(t1))
t2 = timeit(
"count_items_ififif(i, t)",
setup="from __main__ import count_items_ififif, generate_items_and_threshold; i, t = generate_items_and_threshold()",
number=1000,
)
print("count_items_ififif: {:.2f}".format(t2))
if __name__ == "__main__":
run_test()
This outputs (Python 3.8.2, Windows):
count_items_ifelifelse: 6.69
count_items_ififif: 8.71
Roughly 20% faster, because of more unnecessary if
evaluations each loop. The other side of it is that for if/elif/else
the performance will vary based on how the data is sorted, and whether it checks the most occurring condition first.
Upvotes: 2
Reputation: 83
example1
>>> def foo():
a = 10
if a == 10:
print("condition1")
elif a == 10:
print("condition2")
else:
print(0)
>>> foo()
condition1
>>>
elif is guaranteed not to run when if is true.
example2
def foo():
a = 10
if a == 10:
print("condition1")
if a == 10:
print("condition2")
else:
print(0)
>>> foo()
condition1
condition2
>>>
example3 modify if statement of example2.
if a == 10:
print("condition1")
return a
output
>>> foo()
condition1
10
So, in your case adding a return in first if statement has similar operation like an if-elif block. the (return a) is preventing the second if statement to be executed in example3.
Upvotes: 2