Loop Control: break, continue, pass and else
break leaves a loop, continue skips to the next iteration, pass does nothing, and the loop else runs only when no break happened.
- Basics
- Data Types
- Operators
- Strings
- Control Flow
- Lists
- Tuples
- Sets
- Dictionaries
- Comprehensions
- Functions
- Advanced Functions
- Recursion
- Exception Handling
- File Handling
- Modules
- Standard Library
- OOP
- Advanced OOP
- Iterators and Generators
- Decorators
- Context Managers
- Descriptors and Dataclasses
- Python Internals
- Concurrency
- Regular Expressions
- Serialization
- Command Line Python
- Testing and Debugging
- Type Hints
- Performance
- Python Security
- DSA with Python
break
break exits the loop immediately. Nothing else in the body runs, and the loop does not continue.
names = ["Meera", "Arun", "Sara", "Ravi"]
for name in names:
print("checking", name)
if name == "Sara":
print("found")
break
print("finished")checking Meera
checking Arun
checking Sara
found
finishedbreak only leaves one loop
for row in range(3):
for column in range(3):
if column == 1:
break # leaves the INNER loop only
print(row, column)0 0
1 0
2 0To leave both loops, use a flag, the loop else, or - most cleanly - put the loops in a function and return.
def find_in_grid(grid, target):
for r, row in enumerate(grid):
for c, value in enumerate(row):
if value == target:
return r, c # leaves both loops at once
return None
print(find_in_grid([[1, 2], [3, 4]], 3)) # (1, 0)continue
continue skips the rest of the current iteration and starts the next one.
for n in range(1, 11):
if n % 2 == 0:
continue # skip even numbers
print(n, end=" ") # 1 3 5 7 9
print()lines = ["# a comment", "", "host = localhost", " ", "port = 8080"]
for line in lines:
line = line.strip()
if not line:
continue # skip blank lines
if line.startswith("#"):
continue # skip comments
print("setting:", line)This filtering shape - skip everything uninteresting first, then handle the real case at the bottom with no indentation - is one of the best uses of continue.
continue in a while loop needs care
i = 0
while i < 5:
if i == 2:
continue # INFINITE LOOP: i is never incremented
print(i)
i += 1i = 0
while i < 5:
i += 1 # advance FIRST
if i == 3:
continue
print(i)In a for loop the iterator advances by itself, so continue is always safe. In a while loop it jumps straight back to the condition, skipping any increment below it.
pass
pass does nothing at all. It exists because Python blocks cannot be empty.
for n in range(5):
if n == 3:
pass # a placeholder: nothing happens, the loop continues
print(n) # 0 1 2 3 4 - all of them
def not_implemented_yet():
pass
class Marker:
pass
try:
risky()
except ValueError:
pass # deliberately ignore this errorThe three are not interchangeable
| Effect on the loop | Rest of the body | |
|---|---|---|
break | Ends it | Skipped |
continue | Next iteration | Skipped |
pass | None | Runs normally |
The loop else clause
Both for and while may have an else. It runs when the loop finishes without hitting break.
names = ["Meera", "Arun"]
target = "Sara"
for name in names:
if name == target:
print("found")
break
else:
print("not found") # runs, because no break happenedThe keyword is badly chosen. Read else here as "no break", not as "otherwise". It runs after a normal, complete loop.Where it is genuinely useful
def is_prime(n):
if n < 2:
return False
for divisor in range(2, int(n ** 0.5) + 1):
if n % divisor == 0:
return False
return True
print([n for n in range(2, 30) if is_prime(n)])required = ["name", "email", "phone"]
record = {"name": "Meera", "email": "m@example.com", "phone": "9000000000"}
for field in required:
if field not in record:
print("missing", field)
break
else:
print("record is complete")The alternative is a found = False flag set inside the loop and checked afterwards. The else clause removes the flag entirely. Many teams still prefer the flag because it is more obvious to a reader; both are acceptable, and consistency matters more than the choice.
Combining them
entries = ["12", "abc", "-5", "0", "quit", "99"]
for entry in entries:
if entry == "quit":
print("stopping early")
break
if not entry.lstrip("-").isdigit():
print("skipping", entry)
continue
value = int(entry)
if value <= 0:
continue
print("accepted", value)
else:
print("processed every entry")Common mistakes
- Expecting
breakto exit nested loops. It exits one level. - Using
continuein awhileloop above the increment, causing a hang. - Confusing
passwithcontinue.passdoes not skip anything. - Reading the loop
elseas "if the loop did not run". - Using a bare
except: pass, which silently swallows every error including typos. - Putting
breakinside anifwhose condition can never be true.
Best practices
- Use
continueto filter early and keep the main body unindented. - Extract nested loops into a function and use
returninstead of flags. - Use the loop
elsefor search loops, or a clearly named flag - but be consistent. - Never write
except: passwithout a comment explaining why the error is safe to ignore. - Keep the number of exit points in one loop small enough to hold in your head.
Practice
- Search a list of dictionaries for a matching record, reporting failure, using the loop
elseand then using a flag. Compare the two. - Write a nested loop that stops entirely on the first negative value found in a grid.
- Explain why
continuein awhileloop can hang and how to place the increment safely. - Filter a list of raw input strings, skipping blanks and comments, and stop at a line reading
END. - Predict the output of a loop containing all three of
break,continueandpass, then check it.
Conclusion
break leaves, continue skips, pass does nothing. The loop else means "no break happened", and when nesting gets awkward the real answer is usually a function with a return.