Skip to Content
Course content

54: break, continue, and else on Loops

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I was looking through some old log-parsing scripts the other day and realized how often we write loops that do more work than they need to. Most of the time, we aren't actually interested in every single item in a list; we're looking for one specific thing, or we're trying to filter out the garbage. Let's look at a real scenario: we have a list of server status messages, and we need to find if there's a "CRITICAL" failure.

The problem with searching until the end

If I just write a standard for loop, Python is going to visit every single element. Let's try it with a small list of logs:

logs = ["INFO: System boot", "INFO: Network up", "CRITICAL: Disk Failure", "INFO: User logged in", "INFO: Backup started"]

for log in logs:
    if "CRITICAL" in log:
        print("Found the error! Stopping search.")
    # Imagine there is some expensive processing here
    print(f"Processing {log}...")

If you run this, you'll notice that even after it prints "Found the error!", it keeps processing the rest of the logs. That's a waste of CPU cycles. In a real production environment with millions of lines of logs, that's a performance nightmare. I don't care about the "User logged in" message if the disk has already failed.

Cutting the loop short

This is where break comes in. It's a blunt instrument: it tells Python to drop out of the loop immediately, regardless of how many items are left in the sequence. Let's tweak the code:

for log in logs:
    if "CRITICAL" in log:
        print("Found the error! Stopping search.")
        break
    print(f"Processing {log}...")

Now, the moment "CRITICAL: Disk Failure" is hit, the loop terminates. We didn't even look at the "User logged in" log. It's clean, it's fast, and it's exactly what we want when searching for a unique trigger.

Skipping the noise

But what if we have some "noise" in our data? Let's say our log list contains some empty strings or "DEBUG" messages that we just want to ignore entirely without stopping the whole search. I don't want to wrap my entire logic inside a giant if block—that leads to "arrow code" (where your indentation keeps pushing further and further to the right).

Instead, I'll use continue. While break kills the loop, continue just kills the current iteration and jumps straight to the next item.

logs = ["INFO: Boot", "", "DEBUG: Temp check", "CRITICAL: Disk Failure", "INFO: User login"]

for log in logs:
    if not log or "DEBUG" in log:
        continue # Skip these and move to the next log immediately
    
    if "CRITICAL" in log:
        print("Found the error!")
        break
    print(f"Analyzing {log}...")

I personally prefer continue for "guard clauses." By putting the skips at the top, the rest of my loop stays flat and readable. If the log is empty or a debug message, we just bounce back to the top of the loop and grab the next one.

Handling the 'Not Found' scenario

Here is where things get weird. Usually, if we're searching for something, we need to know if we never found it. The old-school way is to create a "flag" variable (like found = False) and flip it to True inside the if block. It works, but it's clunky.

Python has a feature that feels almost like a mistake because the naming is confusing: the else block on a loop. In a loop, else doesn't mean "if the loop didn't run"; it means "if the loop finished naturally without hitting a break."

Let's try it. I'll use a list with no critical errors this time:

safe_logs = ["INFO: Boot", "INFO: Network up"]

for log in safe_logs:
    if "CRITICAL" in log:
        print("Found it!")
        break
else:
    print("Search complete: No critical errors found.")

Because the loop finished all its iterations without ever hitting the break statement, the else block executes. If I change one of those logs to "CRITICAL", the break triggers, and the else block is skipped entirely. It's a very elegant way to handle "search and fail" logic, even if the keyword else feels slightly misplaced here.




📋 Practical Task

Exercise: The Malicious URL Filter

You are building a security filter for a web proxy. You have a list of requested URLs, some of which are empty, some of which are safe, and some of which are known malicious domains.

Write a script that does the following:

  • Iterates through a list of URLs: ["google.com", "", "malware-site.net", "python.org", "evil-domain.com"].
  • If a URL is an empty string, use continue to skip it.
  • If a URL contains the word "malware" or "evil", print "Security Alert: Malicious site blocked!" and use break to stop all further processing immediately.
  • If the loop finishes without finding any malicious sites, use an else block to print "Scan complete: All URLs are safe."
Rating
0 0

There are no comments for now.

to be the first to leave a comment.