Working with Loops and Conditionals
The file search pattern reads through a file line by line, applies a filter condition using string methods, and processes only matching lines.
Why Search Selectively
A text file may contain hundreds or thousands of lines, while your program may need only a small subset. A log file might contain many entries, but your task could be to find only errors. A contact list might contain many names, but you may be looking for one specific name. Processing every line in the same way would do unnecessary work. A targeted file search instead reads each line, checks whether it matches a condition, and processes only the lines that pass.
The central pattern is read, filter, process: read one line, filter it with a condition, and process it only when the condition is true.
The Three-Step Search Pattern
The loop visits the file line by line. For each line, the filter applies a search condition. String operations such as the in operator, startswith, and find can test whether the line contains particular text, begins with a particular prefix, or includes a substring. If the condition is true, the line moves to the processing step. If the condition is false, the line is skipped and the loop continues with the next line.
Tracing One Line
with open("system.log") as file: for line in file: if "ERROR" in line: print(line.strip())
What do you think happens?
Suppose the current line is "INFO: backup complete\n". What happens when the condition is "ERROR" in line?
Reveal answer
Answer: The line is skipped.
The condition is false because the line does not contain ERROR. The processing statement is not reached, so the loop moves to the next line.
Progressing Through the File
The same logic is applied repeatedly as the loop advances from the first line to the last. Each line receives one opportunity to pass the filter. A matching line is processed immediately; a nonmatching line is skipped immediately. The search therefore makes one pass through the file instead of first collecting or processing all lines.
Why Single-Pass Processing Helps
The pattern is useful when the file is large and only a small portion is relevant. Each line is read once, tested immediately, and either processed or skipped. This avoids unnecessary processing of nonmatching lines. It also avoids loading the entire file into memory at once, making the approach memory-efficient for large text files.
| Approach | What happens to each line | Why it matters |
|---|---|---|
| Process every line | Every line moves to processing | Work is performed even for irrelevant data |
| Filter before processing | Only matching lines move to processing | Unnecessary processing is avoided |
Choosing the Search Test
- Use the in operator when the line should contain particular text anywhere.
- Use startswith when the line should begin with a particular prefix.
- Use find when you need to test for a substring's presence or position.
- Place the string test inside the if statement so it is evaluated once for each line.
This example changes the filter rather than the overall pattern. The loop still reads a line, the condition still decides whether it matches, and the processing step still runs only for a matching line. Only the search requirement has changed: the line must begin with Ada.
Mistakes to Avoid
Forgetting to strip whitespace
A line read from a text file may include surrounding whitespace, including the line ending.
Fix:
Use line.strip() when the processing step needs the surrounding whitespace removed.Using case-sensitive comparisons incorrectly
The condition may not match a line containing ERROR when the searched text uses different capitalization.
Fix:
Choose the capitalization used by the file and the search condition carefully.Processing before filtering
The line is already being processed by print before the condition decides whether it belongs in the result.
Fix:
Put the relevant processing statement inside the conditional block.Not closing the file after reading
A file should be closed when reading is finished.
Fix:
Close the file explicitly or use a file-handling structure that closes it after the reading block.
Practice the Pattern
Write a Python file search that reads lines from settings.txt and prints only the lines that contain the text "timeout". Make sure the processing statement is controlled by the conditional and that surrounding whitespace is removed before printing.
Hints
- Open the file and loop through it one line at a time.
- Use the in operator inside an if statement.
- Call strip() in the processing statement.
Tracing a Timeout Search
A file contains three lines: "host=server", "timeout=30", and "mode=safe". The search condition is "timeout" in line.
Read the first line: The line host=server does not contain timeout, so the condition is false and the line is skipped.
Read the second line: The line timeout=30 contains timeout, so the condition is true and the line moves to processing.
Read the third line: The line mode=safe does not contain timeout, so the condition is false and the line is skipped.
Only timeout=30 is processed.
Key Takeaways
- A targeted file search follows the sequence read, filter, process.
- The loop reads one line at a time and the conditional decides whether that line continues.
- String methods and operations such as in, startswith, and find can build the filter condition.
- Single-pass filtering avoids unnecessary processing and avoids loading the entire file into memory at once.
- Strip whitespace, handle capitalization carefully, and close the file after reading.
Key Takeaways
- Search files line by line using the read, filter, process pattern.
- Use string tests such as in, startswith, and find inside a conditional.
- Process only matching lines so irrelevant data is skipped.
- A single-pass search is useful for large files because it avoids unnecessary processing and memory use.
- Remember to remove unwanted whitespace, handle case carefully, and close files.