Introduction
Understand For-Else and While-Else
Syntax
for variable_name in iterable:
#stmts in the loop
.
.
.
else:
#stmts in else clause
.
.
.
while condition:
#stmts in the loop
.
.
.
else:
#stmts in else clause
.
.
.
- The else clause will not be executed if the loop gets terminated by a break statement.
- If a loop does not hit a break statement, then the else clause will be executed once after the loop has completed all its iterations (meaning, after the loop has completed normally).
Simplified Real-World Examples
Are you thinking, what’s the point? How can this be of any use to me? Come, let’s explore some interesting applications which can be useful for you.
A) Search
Traditional Approach
Traditionally, flags were used in search programs to keep a tab on whether a value was found or not. If you had to search for more values, then it increased the complexity of maintaining many flag variables.
Traditionally, flags were used in search programs to keep a tab on whether a value was found or not. If you had to search for more values, then it increased the complexity of maintaining many flag variables.
#************************ Traditionally ************************
# set flag = 0
# loop the items in the data
# if the item was found in the loop then set flag = 1
# display search result by verifying the flag value
#***************************************************************
Better Approach in Python
my_treasure_box = ["a", "b", "Diamond", "c"]
def search(search_item):
for item in my_treasure_box:
if(item==search_item):
print(f"{search_item} Found!")
break
else:
print(f"No {search_item} found.")
search("Diamond")
search("Gold")
#-------Output--------
#Diamond Found!
#No Gold found.
B) To Check Limits
Traditional Approach
Traditionally, a flag variable was used to check if the data has breached given limits.
#*************************Traditionally*************************
# set flag = 1
# loop the items in the data
# if any item breaches the given limits then set flag = 0
# display the validation result by verifying the flag value
#***************************************************************
Better Approach in Python
lower_limit = 5
upper_limit = 10
def validate_limits(input_data):
for i in input_data:
if(i <= lower_limit or i >= upper_limit):
print(f"{input_data}: At least one value breaches limits.")
break
else: #no break
print(f"{input_data}: Successful Validation!")
validate_limits([1, 6, 11])
validate_limits([6, 7, 8])
#------------Output------------
#[1, 6, 11]: At least one value breaches limits.
#[6, 7, 8]: Successful Validation!
C) Nested Loops
Traditional Approach
#************************Older Languages************************
# outer_label: outer loop
# inner loop
# if a condition was met, GOTO outer_label
#***************************************************************
Better Approach in Python
But in Python, there is no GOTO statement and that’s a good thing. In fact, this is one of the reasons why Python introduced break and loop’s else statements ( to replace the GOTO statement). Hence, making it easier and safer for programmers to use them.
- When we have to manage nested loops, we can easily break from an inner loop and get the line of execution to the outer loop using a break statement.
- And if you need to check whether the inner loop completed executing all its iterations normally without hitting a break statement, you could use the loop’s else clause.
To understand this clearly, take a look at the example below.
teams_data = [
{"team_name": "A", "team_scores": [5, 3, 2]},
{"team_name": "B", "team_scores": [4, 2, None]}
]
for team in teams_data:
total_score = 0
name = team["team_name"]
for score in team["team_scores"]:
if score == None:
print(f"Team {name} Score: Incomplete Data")
break
total_score += score
else:
print(f"Team {name} Score: {total_score}")
#------------Output------------
#Team A Score: 10
#Team B Score: Incomplete Data
D) Use with Exception Handling
def multiply(my_data):
result = 1
for i in my_data:
try:
result *= i
except TypeError:
print(f"{my_data}: Invalid Data")
break
else:
print(f"{my_data} Multiplication Result: {result}")
multiply([2, 3, 6])
multiply(['a', 'b'])
#------------Output------------
#[2, 3, 6] Multiplication Result: 36
#['a', 'b']: Invalid Data
Takeaway:
1. The else clause of a loop (for/while) gets executed only if the loop has completed its execution fully without hitting a break statement (in other words, loop has completed normally).
2. The statements inside the loop’s else clause will get executed once after the loop has completed normally.
3. How to keep confusion away? Think of the loop’s else clause as no-break. Always comment #no break next to the loop’s else clause, a best practice for better code readability suggested by Raymond Hettinger, a Python pioneer.
4. Where can you use it?
- To search (instead of using flags, use break and loop’s else).
- To check limits/boundaries (instead of using flags, use break and loop’s else).
- To manage nested loops (when you need to take action based on whether the inner loop got executed normally or hit a break statement).
- You could use it along with exception handling (when you need to break on exception and execute certain statements only if the loop was completed normally).
With this, I hope that you are confident about for-else and while-else in Python. You also got familiar with a few of its applications. Repeat with me “No More Confusion :)”!
Please comment below if you have come across any other applications (uses) of for-else and while-else.