Concepts / Loops: Iterating Through Files

Loops: Iterating Through Files

find() returns the starting index of a substring if found, or -1 if not found

  • Programming

A Search Result with Two Meanings

When a loop reads a file one line at a time, each line can be tested for a substring. The find() method gives the test a precise result: it returns the starting index of the substring when the substring is present, and it returns -1 when the substring is absent. That single integer lets a program decide whether a line should be kept or skipped.

What do you think happens?

What does find() return when the substring is not present in the string?

  • 0
  • -1
  • The length of the string
  • The substring itself
Reveal answer

Answer: -1

find() returns the starting index when it finds the substring. If it cannot find the substring, it returns -1.

Mapping a Match to an Index

String positions are zero-indexed, so the first character is at position 0. When find() locates a substring, it reports the position of that substring's first character. For example, in the generated string "alice@example.com", the at sign begins at position 5. Calling find("@") therefore returns 5, not the position after the at sign and not the number of characters in the string.

match beginsreturns indexno # matchalice@example.comcharacters at positions 0through 165find("@")-1find("#")@position 5
What does find() report when a substring starts at a known character position, and what does it report when no match exists?

Tracing the at sign

Determine the result of searching the generated string "alice@example.com" for the substring "@".

Start counting: Use zero-based positions. The first character, a, is at position 0.

Locate the match: The at sign follows the five characters a, l, i, c, and e, so it begins at position 5.

Interpret the return value: Because the substring is present, find("@") returns the starting index 5.

find("@") returns 5.

Preparing Each File Line

A line read from a file includes the newline character at its end. Before searching, call rstrip() on the line. rstrip() removes trailing whitespace, including the newline, so the search operates on the actual line content. The source material recommends calling rstrip() before searching because leaving trailing whitespace in place can make a search fail unexpectedly or behave strangely.

line = line.rstrip() position = line.find("@")

Filtering Lines with a Conditional

The useful distinction is between the two possible kinds of result. A return value of -1 means the substring was not found, so the line can be skipped. Any other returned integer means the substring was found at that index, so the line can be printed or collected. A conditional makes this decision for every line in the file.

search substring-1index not -1file linefind resultindex or -1skip linecontinuematching lineprint
How does control flow differ when find() returns -1 compared with an index?
python

This pattern first removes trailing whitespace. It then searches the current line for the at sign. If find() returns -1, continue skips the rest of the loop body and moves to the next line. If find() returns an index, the condition is false and the line is printed.

Walking Through the File

The loop applies the same three-stage process to every line: prepare the line with rstrip(), search for the chosen substring, and either skip or keep the line. The loop does not need to know the result from the previous line. Each current line receives its own find() result.

next iterationnext iterationif matchif matchif matchline 1rstrip, findmatching linesprintedline 2rstrip, findline 3rstrip, find
How does the loop move through lines, test each one, and produce matching lines?
read each linecleaned lineindex foundfilelinesrstrip()trim trailing whitespacefind()substring testmatching linesprinted or collected
How does each line move from the file through cleanup and substring testing into the extracted result?
python

In this generated variation, a list named matching_lines receives each line whose find() result is not -1. The same filtering rule can instead print the line immediately. The important mechanism is unchanged: each line is cleaned, searched, and either skipped or retained.

Tracing an Incorrect Search

@ begins at position 10# is absentFromalice@example.combefore search10find("@")Fromalice@example.comafter tracing positions-1find("#")
Which character position does find() return, and how can that position expose a wrong search or condition?

Tracing the integer returned by find() can reveal what went wrong. In the generated line "From alice@example.com", the at sign starts at position 10, so find("@") returns 10. If the search is changed to find("#"), the return value becomes -1 because that substring is not present. Checking the searched substring and the returned index helps distinguish a missing match from an incorrect expectation about its position.

Mistakes in File Searches

  • Treating -1 as if it were a valid matching position.

    -1 means the substring was not found.

    Fix: Skip when the result equals -1, and keep the line when the result is not -1.

  • Forgetting that positions are zero-indexed.

    The first character is at position 0.

    Fix: Count from 0 when tracing the returned index.

  • Searching the raw line before removing trailing whitespace.

    A file line includes its ending newline, and trailing whitespace can make a search fail unexpectedly or behave strangely.

    Fix: Call rstrip() before searching each line.

  • Assuming every nonzero result means no match.

    Any returned index identifies where the substring starts.

    Fix: Only -1 means that the substring was not found.

Practice the Filter

MEDIUM

For each generated line, predict the result of find("@") and decide whether the line is kept by the condition find("@") == -1 followed by continue. Then explain why rstrip() belongs before the search.

Hints
  • Use zero-based positions.
  • A result of -1 means the line is skipped by this pattern.
  • A result other than -1 means the line passes through to the print or collection step.

One line at a time

Trace the generated line "To alice@example.com" when the searched substring is "@".

Clean: Call rstrip() so trailing whitespace, including a line-ending newline when present, is removed.

Search: The at sign begins at position 8 in the generated line, so find("@") returns 8.

Filter: Because 8 is not -1, the skip condition is false and the line is retained.

The line passes the substring filter.

Key Takeaways

  1. find() returns the starting index of a found substring.
  2. The first character has index 0, and -1 means that the substring was not found.
  3. Call rstrip() before searching a line read from a file.
  4. A loop, find(), a conditional, and continue can filter file lines by substring presence.
  5. When debugging, inspect both the searched substring and the integer returned by find().

Key Takeaways

  • find() reports where a substring begins, using zero-indexed positions.
  • A return value of -1 means there is no match.
  • rstrip() should be called before searching each file line.
  • Combining find() with a loop and conditional lets you extract matching lines.
  • Tracing the returned index is a practical way to debug a file-search condition.