Control Flow: Loops and Conditionals
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. The lines may not all have the same structure: a line can be empty, or it may contain fewer words than the program expects. If the program accesses a list index that does not exist, it can crash with an IndexError. Three techniques work together to make this parsing more resilient: continue skips unwanted lines, guardian code checks that an index is safe to access, and the or operator combines multiple skip conditions.
The order of checks matters. A guardian check must happen before the code it protects.
Skipping an Iteration
The continue statement is useful when a loop should ignore the rest of the current iteration. When execution reaches continue, it immediately jumps back to the top of the loop and begins the next iteration. This lets you reject unwanted lines early instead of placing all later processing inside a large conditional branch.
For an input sequence containing an empty line, a line beginning with "Subject", and a line beginning with "From", only the words from the "From" line reach print.Protecting the First Word
A common parsing pattern splits a line into a list named words and then examines words[0], the first word. That access is unsafe when the line produces an empty list. In that case, there is no first element, so the program raises an IndexError before it can evaluate whether the first word is "From".
Guardian code is a defensive check placed before a potentially unsafe operation. For list access, it checks that the list has enough elements before the program accesses the required index.
Tracing Three Lines
Decide what happens when the parser examines an empty line, a line beginning with "Subject", and a line beginning with "From".
- 1Empty line
Splitting produces no words. The length check identifies the empty list, so continue skips the rest of this iteration. words[0] is never accessed.
- 2Subject line
The list contains a first word, so the guarded access is safe. Because the first word is not "From", continue skips the remaining processing.
- 3From line
The list contains a first word and that word is "From", so the line passes both skip conditions and reaches the processing code.
Only the line beginning with "From" reaches the processing code, and the empty line does not cause an IndexError.
Combining Skip Conditions
Two separate if statements can perform the required checks, but the conditions can also be combined. The or operator makes the complete condition true when at least one sub-condition is true. Therefore, the program can skip a line if the list is empty or if its first word is not "From".
if len(words) == 0:
continue
if words[0] != "From":
continueTwo separate skip checks
if len(words) == 0 or words[0] != "From":
continueOne compound skip check
for line in lines:
words = line.split()
if len(words) == 0 or words[0] != "From":
continue
print(words)- 1The loop selects a line for the current iteration.
- 2split produces the words list.
- 3The compound condition checks whether the line should be skipped.
- 4If either sub-condition is true, control returns to the next loop iteration.
- 5Otherwise, the processing statement runs.
- The line is split into a list of words.
- The first condition identifies an empty list.
- The second condition rejects a nonempty list whose first word is not "From".
- If either condition is true, continue skips the rest of the iteration.
- The words list is accessed at index 0 only after the empty-list condition is false.
Only nonempty lines whose first word is "From" reach print.Reliable Guard Placement
Place every guardian check before the operation it protects. For this parsing pattern, check whether the words list is empty before evaluating words[0]. A later check cannot protect an earlier unsafe access.
Common mistake Accessing words[0] before checking whether words contains an element.
What it looks likeif words[0] != "From": continue if len(words) == 0: continueWhy it failsAn empty line causes the first access to fail before the guardian check is reached.
Do this insteadCheck the list length first, then access words[0], or combine the conditions in the safe order.
Common mistake Assuming every parsed line has the same structure.
What it looks likeA parser expects three words from every line.
Why it failsSome lines can be empty or contain fewer words than expected, so an index may not exist.
Do this insteadAnticipate inconsistent structure and add guardian checks before accessing list elements.
Common mistake Using a condition that accepts unwanted lines instead of skipping them.
What it looks likeProcessing every line before checking whether its first word is "From".
Why it failsThe program performs processing on lines that do not meet the criterion.
Do this insteadUse continue to skip lines whose first word is not "From".
Practice the Pattern
Write a loop that receives lines, splits each line into words, skips empty lines, skips lines whose first word is not "From", and processes only the remaining lines.
Hints
- Create the words list before checking its length.
- Use continue for a line that should be skipped.
- Combine the empty-list check and the first-word check with or.
What do you think happens?
What should happen when the current line is empty?
Reveal answer
The guardian condition is true, so continue skips the rest of the iteration.
An empty split result has no first word. The guardian check must therefore cause an immediate continue before words[0] is accessed.
Pattern in Practice
A resilient parsing loop follows a clear order: split the line, guard the list access, reject lines that do not meet the criterion, and process only accepted lines. The continue statement moves control directly to the next iteration. The guardian check prevents an invalid index access, and or lets one skip branch represent multiple reasons for rejection.
Key Takeaways
- Use continue to skip the remaining code in the current loop iteration and move to the next iteration.
- Check a list's length before accessing an index that may not exist.
- Place guardian checks before the operations they protect.
- Use or when either of multiple conditions should cause the same continue action.
- Test parsing logic with empty lines and lines containing fewer words than expected.