Here are 10 tips to help you write cleaner, more efficient, and more "Pythonic"
for loops.---
1️⃣. Use
enumerate() for Index and ValueInstead of using
range(len(sequence)) to get an index, enumerate gives you both the index and the item elegantly.# Less Pythonic 👎
items = ["a", "b", "c"]
for i in range(len(items)):
print(i, items[i])
# More Pythonic 👍
for i, item in enumerate(items):
print(i, item)
---
2️⃣. Use
zip() to Iterate Over Multiple ListsTo loop through two or more lists at the same time,
zip() is the perfect tool. It stops when the shortest list runs out.names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name} is {age} years old.")
---
3️⃣. Iterate Directly Over Dictionaries with
.items()To get both the key and value from a dictionary, use the
.items() method. It's much cleaner than accessing the key and then looking up the value.# Less Pythonic 👎
config = {"host": "localhost", "port": 8080}
for key in config:
print(key, "->", config[key])
# More Pythonic 👍
for key, value in config.items():
print(key, "->", value)
---
4️⃣. Use List Comprehensions for Simple Loops
If your
for loop just creates a new list, a list comprehension is almost always a better choice. It's more concise and often faster.# Standard for loop
squares = []
for i in range(5):
squares.append(i * i)
# squares -> [0, 1, 4, 9, 16]
# List comprehension 👍
squares_comp = [i * i for i in range(5)]
# squares_comp -> [0, 1, 4, 9, 16]
---
5️⃣. Use the
_ Underscore for Unused VariablesIf you need to loop a certain number of times but don't care about the loop variable, use
_ as a placeholder by convention.# I don't need 'i', I just want to repeat 3 times
for _ in range(3):
print("Hello!")
---
6️⃣. Unpack Tuples Directly in the Loop
If you're iterating over a list of tuples or lists, you can unpack the values directly into named variables for better readability.
points = [(1, 2), (3, 4), (5, 6)]
# Unpacking directly into x and y
for x, y in points:
print(f"x: {x}, y: {y}")
---
7️⃣. Use
break and a for-else BlockA
for loop can have an else block that runs only if the loop completes without hitting a break. This is perfect for search operations.numbers = [1, 3, 5, 7, 9]
for num in numbers:
if num % 2 == 0:
print("Even number found!")
break
else: # This runs only if the 'break' was never hit
print("No even numbers in the list.")
---
8️⃣. Iterate Over a Copy to Safely Modify
Never modify a list while you are iterating over it directly. This can lead to skipped items. Instead, iterate over a copy.
# This will not work correctly! 👎
numbers = [1, 2, 3, 2, 4]
for num in numbers:
if num == 2:
numbers.remove(num) # Skips the second '2'
# Correct way: iterate over a slice copy [:] 👍
numbers = [1, 2, 3, 2, 4]
for num in numbers[:]:
if num == 2:
numbers.remove(num)
print(numbers) # [1, 3, 4]
---
9️⃣. Use
reversed() for Reverse IterationTo loop over a sequence in reverse, use the built-in
reversed() function. It's more readable and efficient than creating a reversed slice.