How to Find a Character in a String in Python

Many guides still find a character in a string with a for loop and a counter. It works, but str.find() does it in one call: the index of the first match, or -1 if it’s missing.

Use index() when a miss should raise an error, and in for yes or no. I ran every example on Python 3.12.5.

In this tutorial, I’ll show you how to find a character in a string in Python six ways, up to every position and any case.

The Sample String We’ll Search

Every example searches the same email string, "olivia.parker@example.com": one @, two dots, three as and no #.

Method 1: Find a Character With find() (Recommended)

Use find() when the character might be missing. Same email string, looking for the @:

email = "olivia.parker@example.com"

at = email.find("@")
print("@ is at index", at)
print("user:", email[:at], "| domain:", email[at + 1:])

print("# is at index", email.find("#"))
print("first . after @:", email.find(".", at))

Output:

@ is at index 13
user: olivia.parker | domain: example.com
# is at index -1
first . after @: 21

The @ is at index 13, splitting olivia.parker from example.com. The missing # gives -1.

Command Prompt output of Python str.find() returning index 13 for the @ in an email and -1 for a missing character
find() returns 13 for the @ and -1 for the #.

How does this code work?

Positions start at 0, so the 14th character is index 13. email[:at] and email[at + 1:] slice around it.

The second argument is a start position, so email.find(".", at) skips the first dot and returns 21. The end argument is in my guide to the find() function in Python.

Important: -1 is also a valid index (the last character), so check if pos != -1 before slicing.

Method 2: Find a Character With index() and Catch ValueError

index() works like find() but raises an error on a miss. Pick it when a missing character means bad data. Same string again:

email = "olivia.parker@example.com"

print(email.index("@"))
print(email.index("#"))

Output:

13
Traceback (most recent call last):
  File "C:\pyguides\index_missing.py", line 4, in <module>
    print(email.index("#"))
          ^^^^^^^^^^^^^^^^
ValueError: substring not found

The first call prints 13. The second stops the script with ValueError: substring not found.

Command Prompt traceback of Python str.index() raising ValueError substring not found for a missing character
index() finds the @ at 13, then raises ValueError for the #.

How does this code work?

There’s no -1 to forget, so bad data fails loudly. Use try/except ValueError to skip it instead. Reading email[30] is a different error: string index out of range in Python.

Method 3: Check if a Character Is in a String With the in Operator

If you don’t need the position, use in. It returns True or False:

email = "olivia.parker@example.com"

print("@" in email, "#" in email)

Output:

True False

It prints True False: the @ is there, the # isn’t.

How does this code work?

in stops at the first match but skips the index. Whole words work too, see checking if a Python string contains a substring.

Method 4: Find the Last Occurrence of a Character With rfind()

rfind() searches from the right and returns the last match, handy for a file extension or domain. Same email, last dot:

email = "olivia.parker@example.com"

dot = email.rfind(".")
print("last . is at index", dot, "->", email[dot + 1:])

Output:

last . is at index 21 -> com

The last dot is at index 21, so the slice after it is com.

How does this code work?

The index is still counted from the left; only the direction changes. rindex() raises instead of returning -1. More in finding the last occurrence of a substring in Python.

Method 5: Find All Positions of a Character With enumerate()

find() stops at the first match. To get every position, loop with enumerate() in a list comprehension:

email = "olivia.parker@example.com"

spots = [i for i, ch in enumerate(email) if ch == "a"]
print("a appears at", spots)
print("count:", email.count("a"))

Output:

a appears at [5, 8, 16]
count: 3
Command Prompt output of a Python enumerate list comprehension listing every index of the letter a in a string
The letter a sits at indexes 5, 8 and 16.

How does this code work?

enumerate() pairs each index with its character, and the if keeps the matches. For words, see finding all occurrences of a substring; for totals, counting characters in a string.

How Do You Find a Character Ignoring Case?

find() is case-sensitive. Here’s the same email string with capitals, plus re.search() for a set of characters:

import re

email = "Olivia.Parker@Example.com"

print(email.find("p"))
print(email.lower().find("p"))

m = re.search(r"[@#!]", email)
print(m.group(), "at index", m.start())

Output:

18
7
@ at index 13
Command Prompt output of Python find() missing a capital P, lower().find() matching it, and re.search finding the @
find("p") returns 18; the lowercased copy returns 7.

How does this code work?

Lowercasing a copy makes P and p equal, and the index still fits the original because the length doesn’t change.

re.search(r"[@#!]", email) matches any bracketed character; m.start() is its index. For digits, see finding the first number in a string.

Which Method Should You Use to Find a Character?

MethodReturnsWhen missingUse it for
s.find(ch)First index-1Most lookups
s.index(ch)First indexValueErrorRequired characters
ch in sTrue/FalseFalseYes/no checks
s.rfind(ch)Last index-1Extensions, domains
enumerate()List of indexes[]Every position

Things to Keep in Mind When You Find a Character

  • Check for -1 before slicing.
  • Searches are case-sensitive; use a lower() copy.
  • Lists have no find(); list.index() raises ValueError on a miss too.

Related string guides worth opening next:

Frequently asked questions

How do I find the position of a character in a Python string?

Use s.find(ch): the first index, or -1 if it’s missing.

What’s the difference between find() and index()?

On a miss, find() returns -1 and index() raises ValueError.

How do I check if a string contains a character?

Use ch in s.

How do I find every position of a character?

Use [i for i, c in enumerate(s) if c == ch].

How do I find a character from the end of a string?

Use s.rfind(ch).

Where is str.find() documented?

See str.find() in the Python docs.