Debugging and Error Handling
Use the continue statement to skip lines that do not meet your criteria, jumping immediately back to the next iteration of the loop.
The Hidden Risk in Line Parsing
When a program parses a file line by line, it may split each line into words and then inspect particular words. The danger is that lines do not always have the same structure. A line may be empty, or it may contain only one word when the program expects more. Accessing a list index that does not exist causes an IndexError and crashes the program. Defensive control flow prevents the program from making that unsafe access.
The three techniques in this lesson work together: continue skips unwanted lines, guardian code checks that an access is safe, and or combines several skip conditions into one readable decision.
Skipping Unwanted Iterations
When parsing a file, you may care only about lines that begin with the word From. A continue statement handles the lines that do not qualify. When the condition for skipping is met, continue immediately jumps back to the top of the loop. The remaining statements in the current iteration are not executed, and the loop moves on to the next line.
for line in lines: words = line.split() if words[0] != "From": continue process_line(words)
Why the First Check Can Fail
What do you think happens?
What happens when an empty line reaches the expression words[0]?
Reveal answer
Answer: The program raises an IndexError before it can execute continue.
An empty line produces no words, so there is no element at index 0. The program must check that the list contains an element before accessing words[0].
The continue statement cannot protect an expression that fails before the condition is evaluated. In the earlier pattern, words[0] is evaluated as part of the if condition. If words is empty, the program crashes while trying to obtain its first element. The missing step is a guardian check placed before the access it protects.
Guarding List Access
Guardian code is a defensive check that verifies whether an operation is safe before allowing it to happen. For a list of words, the program checks the list length before accessing an index. If the list is empty, continue skips the line. Only after this check succeeds may the program safely inspect words[0].
Protecting the First-Word Check
A parser should process only lines whose first word is From, but some input lines may be empty.
Split the line: The line becomes a list named words.
Check the length: If len(words) is 0, the line has no first word, so continue skips it before any index access.
Inspect the first word: The expression words[0] is reached only after the guardian check confirms that an element exists.
Skip or process: A nonmatching first word causes another continue; a first word of From reaches the processing step.
The parser avoids accessing a nonexistent first element and processes only lines that meet the required criterion.
Combining Skip Conditions
Two separate if statements can both use continue: one for an empty list and one for a first word that is not From. This works, but the conditions can be combined. The or operator makes the complete condition true when at least one of its component conditions is true. Therefore, the line is skipped if it is empty or if its first word is not From.
| Line condition | Overall skip condition | Result |
|---|---|---|
| The list is empty | True or ... | continue skips the line |
| The first word is not From | ... or True | continue skips the line |
| The list is not empty and the first word is From | False or False | The line reaches processing |
The or expression is true when at least one skip condition is true.
A Complete Defensive Pattern
for line in lines: words = line.split() if len(words) == 0 or words[0] != "From": continue process_line(words)
This pattern is compact without removing the safety check. The guardian condition comes first inside the compound expression, and the filtering condition follows it. The continue statement has one clear job: leave the current iteration whenever the line should not be processed.
Mistakes That Cause Crashes
Accessing words[0] before checking whether the list has an element.
An empty line produces an empty list, so index 0 does not exist and the program raises IndexError.
Fix:
Check the list length first, then access words[0] only when the list is not empty.Putting the guardian check after the protected access.
The unsafe access has already happened before the length check can help.
Fix:
Place the guardian check before every access it protects.Processing every line without filtering.
Lines that do not meet the required criterion are processed instead of being skipped.
Fix:
Use continue to move immediately to the next iteration when a line does not qualify.Repeating separate skip blocks when one compound condition is clearer.
The logic works, but combining related skip conditions can reduce duplication and improve readability.
Fix:
Use one if statement with or when either condition should cause the same continue action.
Practice the Control Flow
Rewrite a line-parsing loop so that it processes only nonempty lines whose first word is From. Use one compound if statement with or and place continue in that statement.
Hints
- Split each line into a list named words.
- The first condition should identify an empty list.
- The second condition should identify a first word that is not From.
- Both conditions should lead to the same continue statement.
Tracing Three Kinds of Lines
Predict the control-flow result for an empty line, a line beginning with To, and a line beginning with From.
Empty line: Splitting produces no words. The length condition is true, so continue skips the iteration before words[0] is accessed.
Line beginning with To: The list is not empty, but the first word is not From. The second condition is true, so continue skips the iteration.
Line beginning with From: The list is not empty and the first word is From. Both skip conditions are false, so the line reaches processing.
Only the line beginning with From reaches the processing step, while the empty and nonmatching lines are skipped safely.
Reliable Parsing Habits
- Identify which lines your parser actually needs to process.
- Use continue to leave an iteration as soon as a line fails the required criterion.
- Check a list's length before accessing an index.
- Place guardian checks before the code they protect.
- Combine skip conditions with or when either condition should produce the same result.
- Test with empty lines and lines containing fewer words than expected.
Debugging is not only about reacting after a crash. In this pattern, error handling is built into the control flow: unsafe input is recognized early, the current iteration is abandoned, and only data that passes the checks is processed.
Key Takeaways
- continue immediately moves control to the next loop iteration, skipping the remaining statements for the current line.
- Accessing a nonexistent list index can raise IndexError, especially when parsing empty or inconsistently structured lines.
- Guardian code checks the list length before an index is accessed.
- The or operator makes a combined skip condition true when at least one component condition is true.
- Robust parsing places checks before protected operations and tests edge cases such as empty lines.