File Input and the open() Function
A file line includes the newline character at its end when it is read in a for loop.
Try it: Reading and Writing Text Files
How open() returns a file object with a position pointer, how read(), read(n), readline(), readlines() and for line in fh advance it (and return '' at the end), how 'w' and 'a' modes change the file, and why a closed file (after close() or a with block) can no longer be read.
How it works
- open(name, 'r') starts the pointer at 0; 'w' empties the file first; 'a' starts at the end.
- read() returns everything from the pointer to the end; read(n) at most n characters; readline() up to and including the next \n; each moves the pointer past what it returned.
- At the end of the file every read returns '' (an empty string), which is how loops know to stop; for line in fh reads line by line the same way.
- write() text waits in a buffer and reaches the file when it is closed (or the program ends); reading a 'w'/'a' file or writing an 'r' file raises io.UnsupportedOperation.
- close(), or leaving a with block, closes the file; any further read raises ValueError: I/O operation on closed file.
Default run (10 steps): Ready: notes.txt holds 4 lines (51 characters). Nothing is open yet. … Finished. notes.txt now holds "From: stephen\nSubject: meeting\nFrom: louis\nThanks!\n".
Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. One virtual text file with \n line endings (as on Linux/macOS), positions counted in characters (ASCII only), and a write buffer that is only flushed by close() or the end of the program.
Loading the simulation…
A Search Produces a Position
When find() searches a string, it returns one integer. If the substring exists, the integer identifies the character position where that substring starts. If the substring does not exist, find() returns -1. This makes the method useful for examining file lines and deciding which lines should be kept.
The first character has index 0, not index 1. A returned index is the starting position of the complete substring.
What do you think happens?
In the string From: alice@example.com, what does find() return when searching for @?
Reveal answer
11
The first character is at index 0. Counting from zero, the @ character is at index 11.
Mapping Characters to Indexes
To debug find(), write the string out with its character positions. In the generated example below, the search substring is @. The returned value is not a count of all characters and not a true-or-false result. It is the position of the first character in the substring.
Tracing an Email Address
Determine the result of searching for @ in the string From: alice@example.com.
- 1Start at index 0
The first character, F, is at position 0, so every later character is counted from that starting point.
- 2Count to the match
The @ character appears after the characters From: and the space and the five letters in alice. Its zero-based position is 11.
- 3Interpret the result
find()returns 11 because the searched substring begins at index 11.
The search returns 11.
Three Return Values
| find() result | Meaning | Typical interpretation |
|---|---|---|
| 0 | The substring starts at the first character. | The line begins with the searched substring. |
| A positive index | The substring starts later in the string. | The line contains the substring after one or more earlier characters. |
| -1 | The substring was not found. | Reject or skip the string when filtering for the substring. |
The integer returned by find() tells you where the substring starts or that no match exists.
Filtering Lines from a File
The useful file-search pattern combines three actions: open the file, process each line in a loop, and use find() inside a conditional statement. The line is cleaned with rstrip() before the search. If find() returns -1, continue skips that line. Otherwise, the line is printed.
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
if line.find('From:') == -1:
continue
print(line)- 1The
open()call opens the file namedmbox-short.txt. - 2The for loop obtains one line at a time from the opened file.
- 3
rstrip()removes trailing whitespace before the search. - 4
find('From:')returns either the starting index of From: or -1. - 5When the result is -1, continue moves to the next line without printing.
- 6When the result is not -1,
print(line)displays the matching line.
- Open
mbox-short.txtso its lines can be processed. - Process each line from the opened file.
- Remove trailing whitespace, including the line-ending newline.
- Search for the substring From: and compare the result with -1.
- Skip this line when the substring was not found.
- Print the line when
find()returned an index rather than -1.
From: alice@example.com
From: bob@example.comFollowing the Matching Data
Each file line follows the same path: it comes from the opened file, has trailing whitespace removed, and is tested with find(). A line whose result is -1 leaves the output collection because continue skips it. A line whose result is 0 or a positive index passes the test and is printed. The method therefore acts as a filter rather than merely reporting a position.
Treat the return value as diagnostic information. When a line is unexpectedly accepted or rejected, inspect the exact integer from find(), then compare that result with -1. This reveals whether the substring was found and where it began.
Mistakes with File Searches
Common mistake Treating 0 as if it meant no match.
What it looks likeA line begins with From:, so find('From:') returns 0.Why it failsZero is a valid index. It means the substring starts at the first character.
Do this insteadUse -1 as the not-found result. A result of 0 or a positive index means that the substring was found.
Common mistake Checking only for a positive result.
What it looks likeA condition accepts the line only when find('From:') is greater than 0.
Why it failsThat condition rejects a valid match at index 0.
Do this insteadTest whether the result is -1 when you need to distinguish absence from presence.
Common mistake Searching before removing trailing whitespace.
What it looks likeThe loop searches the line exactly as it was read from the file.
Why it failsA line read from a file includes a newline character at the end, and trailing whitespace can make searches behave unexpectedly.
Do this insteadCall rstrip() before calling find() so the search uses the line's content without trailing whitespace.
Common mistake Assuming find() returns the number of matching characters.
What it looks likeThe search for From: returns 5 because the substring has five characters.
Why it failsfind()returns the starting index, not the length of the substring.Do this insteadTrace the characters from index 0 and identify where the first character of the searched substring begins.
Practice the Trace
For each string, determine the result of find('cat'). Then decide whether the line would be printed by a filter that skips only when the result equals -1: catalog, bobcat, and dog.
Hints
- Start counting at index 0.
- The substring can begin at index 0 or at a positive index.
- Only a result of -1 causes the line to be skipped.
Checking the Practice Strings
Determine the find('cat') result for catalog, bobcat, and dog.
- 1catalog
The substring cat starts at the first character, so the result is 0. The line passes the filter.
- 2bobcat
The substring cat starts after bob. With zero-based indexing, its starting position is 3. The line passes the filter.
- 3dog
The substring cat is absent, so the result is -1. The line is skipped.
catalog and bobcat are accepted; dog is rejected.
Key Takeaways
- 1
find()returns the starting index of a found substring. - 2Indexes are zero-based, so the first character is at position 0.
- 3A result of 0 is a valid match at the beginning, a positive result is a match later in the string, and -1 means no match.
- 4For file filtering, open the file, process each line, call
rstrip(), and usefind()in a conditional statement. - 5When debugging, trace the returned index and check whether it equals -1.
At a glance
find()reports where a substring begins or returns -1 when it is absent.- The returned position uses zero-based indexing.
- A file-search loop can use
rstrip(),find(), and continue to filter lines. - Checking the exact integer returned by
find()is a reliable way to debug substring searches.