Loops in Python: for, while, and Beyond
Loops are control flow statements that allow you to execute a block of code repeatedly. This is
fundamental to programming, enabling automation, data processing, and efficient task execution.
Python offers two primary types of loops: for loops and while loops.
1. The for Loop: Iterating Over Sequence
The for loop is used to iterate over a sequence (like a list, tuple, string, or range) or other
iterable objects. It executes a block of code once for each item in the sequence.
OR
The for loop in Python is used to repeat a block of code for every element in a sequence (like a list, tuple, string, or range).
It helps you automate repetitive tasks.
Syntax:
for variable in iterable:
# Code block to execute for each item
# (Indented)
Key Points :
- variable: A temporary variable that takes on the value of each item in the iterable during each iteration.
- iterable: Any object that can be iterated over (e.g., lists, tuples, strings, ranges, dictionaries, sets, files, custom iterators).
- The loop continues until all items in the iterable have been processed.
Examples:
1.1. Iterating over a list:
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(f"I like {fruit}.")
# Output:
I like apple.
I like banana.
I like cherry.
1.2. Iterating over a string (characters):
name = "Python"
for char in name:
print(char)
# Output:
P
y
t
h
o
n
1.3. Iterating using range( ) (Numbers):
range( ) is a built-in function that generates a sequence of numbers. It's commonly used with for loops.
- range(stop): Generates numbers from 0 up to (but not including) stop.
- range(start, stop): Generates numbers from start up to (but not including) stop.
- range(start, stop, step): Generates numbers from start up to (but not including) stop, incrementing by step.
# From 0 to 4 (exclusive of 5)
for i in range(5):
print(i) # Output: 0, 1, 2, 3, 4
print("-" * 10)
# From 2 to 5 (exclusive of 6)
for i in range(2, 6):
print(i) # Output: 2, 3, 4, 5
print("-" * 10)
# From 1 to 10, incrementing by 2
for i in range(1, 11, 2):
print(i)
# Output: 1, 3, 5, 7, 9
1.4. Iterating over a dictionary:
- By default, iterating over a dictionary iterates over its keys.
- Use .values( ) to iterate over values.
- Use .items( ) to iterate over key-value pairs.
student_scores = {"Alice": 95, "Bob": 88, "Charlie": 72}
print("Iterating over keys:")
for name in student_scores: # Or student_scores.keys()
print(name)
print("\nIterating over values:")
for score in student_scores.values():
print(score)
print("\nIterating over key-value pairs:")
for name, score in student_scores.items(): # Unpacking the (key, value) tuple
print(f"{name}: {score}")
# Output:
Iterating over keys:
Alice
Bob
Charlie
Iterating over values:
95
88
72
Iterating over key-value pairs:
Alice: 95
Bob: 88
Charlie: 72
2. The while Loop: Repeating Until a Condition is Met
The while loop repeatedly executes a block of code as long as a specified condition is True.
OR
While loop will run a piece of code while a condition is True. it is based on a boolean condition.
Syntax:
while condition:
# Code block to execute as long as condition is True
# (Indented)
Key Points :
- condition: A boolean expression that is evaluated before each iteration.
- If the condition is initially False, the loop body will not execute even once.
- It's crucial to include code within the loop body that eventually makes the condition False, otherwise,
you'll create an infinite loop.
Examples:
2.1. Counting up to a number :
count = 1
while count <= 5:
print(count)
count += 1 # Increment count to eventually make the condition False
# Output:
1
2
3
4
5
2.2. User input until a specific value :
user_input = ""
while user_input != "quit":
user_input = input("Enter something (type 'quit' to exit): ")
if user_input != "quit":
print(f"You entered: {user_input}")
# Sample Output:
Enter something (type 'quit' to exit): Hello
You entered: Hello
Enter something (type 'quit' to exit): 123
You entered: 123
Enter something (type 'quit' to exit): quit
#No output is printed after "quit" because the condition user_input != "quit" fails, and the loop exits.
Explanation :
- This is a while loop that keeps asking the user for input until the user types "quit".
- If the input is not "quit", it prints what the user typed.
- When the user finally types "quit", the loop stops and nothing more is printed.
2.3. Infinite Loop (and how to avoid/handle it) :
An infinite loop occurs when the loop's condition never becomes False. This will freeze your program.
# DANGER: This is an infinite loop!
# while True:
# print("This will print forever...")
# To stop an infinite loop in most environments (like a terminal), press Ctrl+C.
Always ensure your while loop has a mechanism to terminate.
3. Loop Control Statements
Python provides specific statements to alter the normal execution flow of loops:
3.1. break Statement :
The break statement immediately terminates the loop (both for and while) and transfers control
to the statement immediately following the loop.
Examples:
for i in range(1, 10):
if i == 5:
print("Breaking loop at 5!")
break
print(i)
print("Loop finished.")
# Output:
1
2
3
4
Breaking loop at 5!
Loop finished.
3.2. continue Statement :
The continue statement skips the rest of the current iteration of the loop and proceeds to the next iteration.
Examples:
for i in range(1, 6):
if i % 2 == 0: # If i is even
print(f"Skipping even number: {i}")
continue # Skip the rest of this iteration
print(f"Odd number: {i}")
# Output:
Odd number: 1
Skipping even number: 2
Odd number: 3
Skipping even number: 4
Odd number: 5
3.3. pass Statement :
The pass statement is a null operation; nothing happens when it executes. It's often used as a
placeholder where syntax requires a statement but you don't want any code to execute yet.
Examples:
# Placeholder for future code
for item in some_list:
if item.is_valid():
pass # TODO: Implement validation logic here later
else:
print("Invalid item found.")
4. else Clause with Loops (Advanced)
Both for and while loops can have an optional else block. The code in the else block executes only
if the loop completes without encountering a break statement.
Example 4.1: for loop with else :
numbers = [1, 3, 5, 7, 9]
search_item = 6 # Item not in list
for num in numbers:
if num == search_item:
print(f"{search_item} found in the list!")
break # This break will prevent the else block from executing
else: # Executes if loop completes normally (no break)
print(f"{search_item} not found in the list.")
print("-" * 20)
numbers = [1, 3, 5, 7, 9]
search_item = 5 # Item is in list
for num in numbers:
if num == search_item:
print(f"{search_item} found in the list!")
break
else:
print(f"{search_item} not found in the list.")
# Output:
6 not found in the list.
--------------------
5 found in the list!
Example 4.2: while loop with else :
count = 0
while count < 3:
print(f"Count is {count}")
count += 1
else: # Executes because the loop finished naturally (count reached 3)
print("While loop finished normally.")
print("-" * 20)
count = 0
while True: # An infinite loop without a break
print(f"Count is {count}")
count += 1
if count == 2:
print("Breaking the while loop!")
break # This break will prevent the else block from executing
else:
print("While loop finished normally.") # This will NOT print
# Output:
Count is 0
Count is 1
Count is 2
While loop finished normally.
--------------------
Count is 0
Count is 1
Breaking the while loop!
Use Case for else with loops: This else clause is particularly useful for "search" loops,
where you want to perform an action if an item is not found after checking all possibilities.
5. Nested Loops (Advanced Basic)
You can place a loop inside another loop. This is called nesting. Nested loops are commonly used for
tasks like iterating over 2D data structures (matrices), or generating combinations.
Example 5.1: Printing a multiplication table :
print("Multiplication Table:")
for i in range(1, 4): # Outer loop for rows
for j in range(1, 4): # Inner loop for columns
print(f"{i} * {j} = {i*j}", end="\t") # '\t' for tab spacing
print() # New line after each row
# Output:
Multiplication Table:
1 * 1 = 1 1 * 2 = 2 1 * 3 = 3
2 * 1 = 2 2 * 2 = 4 2 * 3 = 6
3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
Example 5.2: Generating coordinate pairs :
for x in range(3): # x values: 0, 1, 2
for y in range(2): # y values: 0, 1
print(f"({x}, {y})")
# Output:
(0, 0)
(0, 1)
(1, 0)
(1, 1)
(2, 0)
(2, 1)
Key point for nested loops: The inner loop completes all its iterations for each single iteration of the outer loop.
6. Loop Optimizations and Advanced Techniques
6.1. enumerate( ) for Index and Value :
When you need both the index and the value while iterating, enumerate( ) is highly efficient and Pythonic.
Example :
my_list = ["apple", "banana", "cherry"]
for index, value in enumerate(my_list):
print(f"Index {index}: {value}")
# Output:
Index 0: apple
Index 1: banana
Index 2: cherry
6.2. zip() for Parallel Iteration :
zip( ) combines multiple iterables element-wise. It stops when the shortest iterable is exhausted.
Example :
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 22]
for name, age in zip(names, ages):
print(f"{name} is {age} years old.")
# Output:
Alice is 25 years old.
Bob is 30 years old.
Charlie is 22 years old.
6.3. List Comprehensions (Advanced for loop shortcut) :
A powerful and concise way to create lists based on existing iterables, often replacing simple for loops.
Syntax :
Mapping: [expression for item in iterable]
Filtering: [expression for item in iterable if condition]
# Traditional loop to square numbers
squares_loop = []
for i in range(5):
squares_loop.append(i**2)
print(f"Squares (loop): {squares_loop}") # Output: [0, 1, 4, 9, 16]
# List comprehension for squares
squares_comp = [i**2 for i in range(5)]
print(f"Squares (comprehension): {squares_comp}") # Output: [0, 1, 4, 9, 16]
# Filtering even numbers
even_numbers = [num for num in range(10) if num % 2 == 0]
print(f"Even numbers: {even_numbers}") # Output: [0, 2, 4, 6, 8]
6.4. Dictionary and Set Comprehensions :
Similar to list comprehensions, for creating dictionaries and sets.
# Dictionary comprehension
word = "hello"
char_counts = {char: word.count(char) for char in set(word)}
print(f"Character counts: {char_counts}") # Output: {'e': 1, 'o': 1, 'l': 2, 'h': 1}
# Set comprehension
unique_squares = {x**2 for x in [1, 2, 2, 3, 4, 4, 5]}
print(f"Unique squares: {unique_squares}") # Output: {1, 4, 9, 16, 25}
6.5. Generator Expressions (Lazy Evaluation) :
Similar to list comprehensions but use parentheses ( ) instead of square brackets [ ]. They create
generators, which are iterators that produce values one at a time on demand (lazy evaluation),
saving memory for large datasets.
# List comprehension (creates entire list in memory)
list_of_squares = [x*x for x in range(1000000)]
# Generator expression (creates values on the fly)
gen_of_squares = (x*x for x in range(1000000))
# You can iterate over a generator
for sq in gen_of_squares:
# process sq
if sq > 100:
break
When to choose for vs. while?
for loop: Use when you know in advance how many times you need to loop, or when you need to
iterate over a collection of items (lists, strings, ranges, etc.). It's ideal for definite iteration.
while loop: Use when the number of iterations is unknown and depends on a condition being met.
It's ideal for indefinite iteration, such as waiting for user input, reading from a file
until an end-of-file marker is reached, or simulating a game loop.
Common Pitfalls :
Infinite Loops: Always ensure your while loop condition eventually becomes False.
Modifying a list while iterating over it: This can lead to unexpected behavior.
If you need to modify a list, it's often safer to iterate over a copy or build a new list.
my_list = [1, 2, 3, 4]
# DON'T DO THIS without careful consideration!
# for item in my_list:
# if item == 2:
# my_list.remove(item) # Modifies list during iteration!
# Output might be [1, 3, 4] but often skips items.
# Instead, create a new list or iterate over a copy:
new_list = [item for item in my_list if item != 2]
# Or:
# for item in list(my_list): # Iterate over a copy
Off-by-one errors with range( ) or while conditions: Carefully check your start, stop, and step values
in range( ), and boundary conditions in while
loops ( <= vs < ).
Incorrect Indentation: Python relies heavily on indentation to define code blocks.
Incorrect indentation will cause IndentationError or logical errors.