`”banana”.find(“pear”)` returns `-1` when the text is absent. I’m fascinated that a failed search has a clear result, while `-1` can still act as a valid slice position.

You can separate the idea of a text fragment from the operation used to locate one. You’ll connect “substring” to a contiguous stretch of text and see how its positions are represented in Python.

What a substring means in Python

A substring is a contiguous run of text selected from a larger string, and Python represents strings as immutable sequences of Unicode code points.

Python’s str documentation treats indexing and slicing as sequence operations. Slice notation selects the positions you want and returns a string.

Python strings have no method named substring, so use square-bracket slicing for a contiguous range.

Position 0 1 2 3 4 5
Character in banana b a n a n a

The slice text[1:4] returns ana because position 4 is the first position left out of the result.

Choose the operation by the result you need

Start with the value your next line of code needs. Each string operation answers a different question.

  • Text from known positions: use a slice such as text[1:4].
  • A yes-or-no test: use needle in text.
  • The first matching position: use text.find(needle), which returns -1 when no match exists.
  • A count of non-overlapping matches: use text.count(needle).
  • Fields separated by a delimiter: use text.split(separator), which returns a list.

Extract, check and count a substring

In banana, ana starts at indexes 1 and 3, which makes the overlap visible. The slice text[1:4] returns ana because position 4 is excluded.

Negative indexes count backward from the end, so a slice can select a suffix without calculating the string length first.

Membership returns True or False. find returns the lowest index or -1, and count gives the number of non-overlapping occurrences.

Omitted slice bounds use the beginning or end of the string. Negative indexes count from the end, so a suffix needs no prior length calculation.

The list comprehension tests startswith at every candidate index and stops after len(text) – 1. Neither input string changes.

python3.14 substring_demo.py
text = "banana"
needle = "ana"

piece = text[1:4]
print("slice:", piece)
print("contains:", needle in text)
print("first index:", text.find(needle))
print("non-overlapping count:", text.count(needle))

overlapping_indexes = [
    index for index in range(len(text))
    if text.startswith(needle, index)
]
print("overlapping indexes:", overlapping_indexes)

missing_index = text.find("pear")
print("missing index:", missing_index)
print("case-sensitive check:", "Ana" in text)
CPython 3.14.7 shows the slice, first match, count and overlapping match positions.

The first ana starts at index 1, so find returns 1. Count returns one because the second ana starts before the first has ended.

The list comprehension checks every possible start and finds both 1 and 3. For additional bounds examples, see our string slicing explanation.

The Python count method explanation covers optional start and end positions, and the official str.count reference documents the non-overlapping rule.

Know where each operation stops

Slices and searches return different results at the edges. Check a search result before reusing it as an index.

Case Python behavior What to do
The slice stop The stop index is excluded. Use text[start:stop] when you want positions from start up to stop.
A stop past the string end Slicing returns the available characters. Use a slice when a range may extend beyond the current length.
A missing match find returns -1. index raises ValueError. Check for -1 before using a search result as an index.
Different capitalization Membership and string searches compare exact case. Apply casefold() to both strings for caseless matching.
Overlapping matches count skips a match that overlaps the previous one. Test each possible starting position when overlap matters.

Using a failed find result in text[position:] selects the final character because -1 is a valid negative slice index. Test the search result before slicing.

Use split for delimiter-separated fields, and use slicing to select known character positions.

Start with the result you need

When capitalization can vary in your input, test the comparison rule before building later steps around it. This sample line checks whether Ana matches the lowercase text value.

print("case-sensitive check:", "Ana" in text)

Frequently asked questions

A slice returns a string, so you can compare its contents with another string using the equality operator.

How can I compare a substring in Python?

Extract the range with slicing, then compare the result with the expected string using equality. Python returns True when both strings contain the same characters in the same order.

Share.
Leave A Reply