🐍 Python Course · Stage 1 · Lesson 5 of 89 · String Methods
Course Overview →

🟩 Start with the Beginner tab. Read it fully before moving on.

← f-strings Control Flow & Loops →
thecodex.expert · The Codex Family of Knowledge
Python

String Methods in Python

Python strings come with over 40 built-in methods for searching, splitting, transforming, and validating text — the everyday tools of text processing.

Python 3.13 docs.python.org Last verified:
Canonical Definition

Python str objects provide a fixed set of methods defined in the Python Language Reference. Because strings are immutable, every method that "modifies" a string actually returns a new string, leaving the original unchanged.

🟩 Beginner

Everyday text transformation

What you’ll learn: The dozen string methods you’ll use daily — case conversion, whitespace stripping, searching, and replacing. Plus the crucial fact that strings are immutable, so methods return new strings.

How to read this tab: Run each example in the Playground and confirm the original string is unchanged. That immutability is the concept that matters most.

⏱ 30 min📄 2 sections🔶 Prerequisite: Variables & Types
The idea

A string method is an action you run on text: make it uppercase, find a word, replace a phrase, strip whitespace. Because Python strings are immutable, these methods never change the original — they return a brand-new string.

💡

The original string never changes. Every "modifying" method returns a new string. name.upper() gives you an uppercase copy; name is untouched. To keep the result, reassign: name = name.upper().

The most-used string methods

These ten methods cover the vast majority of everyday text work. Each returns a new string (or a value) — the original is never modified.

Pythoncore_methods.py
text = "  Hello, World!  "

# Case
print(text.upper())        # "  HELLO, WORLD!  "
print(text.lower())        # "  hello, world!  "
print("priya".capitalize())# "Priya"
print("priya kumar".title())# "Priya Kumar"

# Whitespace removal
print(text.strip())        # "Hello, World!"  (both ends)
print(text.lstrip())       # "Hello, World!  " (left only)
print(text.rstrip())       # "  Hello, World!" (right only)

# The original is unchanged — strings are immutable
print(text)                # "  Hello, World!  " — untouched

# Length is a function, not a method
print(len("Python"))       # 6
Strings are immutable

text.upper() does not change text — it returns a new string. If you want to keep the result, assign it: text = text.upper(). This trips up beginners who expect the method to modify the variable in place.

💡

Use in for membership, not find. To check if a substring exists, "cat" in text is clearer than text.find("cat") != -1. Reserve find/index for when you need the actual position.

Pythonsearch_replace.py
s = "the quick brown fox"

# Membership — use 'in', not a method
print("quick" in s)        # True

# Find position (returns -1 if not found)
print(s.find("brown"))     # 10
print(s.find("cat"))       # -1  (not found — no error)
print(s.index("brown"))    # 10  (like find, but raises ValueError if missing)

# Count occurrences
print(s.count("o"))        # 2

# Replace (returns a new string)
print(s.replace("quick", "slow"))  # "the slow brown fox"

# Starts / ends with
print(s.startswith("the")) # True
print(s.endswith("fox"))   # True
print("file.pdf".endswith((".pdf", ".doc")))  # True — accepts a tuple

✅ Beginner tab complete

  • I know upper/lower/strip/replace return NEW strings (the original is unchanged)
  • I can search text with in, find, and index — and know find returns -1 while index raises
  • I can use startswith/endswith, including with a tuple of options
  • I know len() is a function, not a method

Continue to f-strings →

🔵 Intermediate

Splitting, joining, and validation

What you’ll learn: split and join (the backbone of parsing and assembling text), plus the validation methods (isdigit, isalpha) and alignment methods (zfill, ljust, center).

How to read this tab: Master the split/join pair first — they are the two most important string operations in real code.

⏱ 30 min📄 2 sections🔶 Prerequisite: Beginner tab

join is called on the separator, and reads backwards at first. ", ".join(items) — the separator owns the method because join must accept any iterable of strings. And join only works on strings: convert numbers first with str(n) or a generator expression.

Splitting and joining

Splitting turns a string into a list; joining turns a list back into a string. These two operations are the backbone of text parsing and assembly.

Pythonsplit_join.py
# split — string to list
csv = "Priya,30,Mumbai"
print(csv.split(","))            # ['Priya', '30', 'Mumbai']

# split with no argument splits on ANY whitespace, collapsing runs
print("a  b   c".split())        # ['a', 'b', 'c']

# maxsplit limits the number of splits
print("a-b-c-d".split("-", 1))   # ['a', 'b-c-d']

# splitlines — split on line boundaries
print("line1\nline2\nline3".splitlines())  # ['line1', 'line2', 'line3']

# join — list to string (called on the SEPARATOR)
parts = ['Priya', '30', 'Mumbai']
print(",".join(parts))           # "Priya,30,Mumbai"
print(" ".join(["Hello", "World"]))  # "Hello World"

# join only works on strings — convert numbers first
nums = [1, 2, 3]
print("-".join(str(n) for n in nums))  # "1-2-3"

# partition — split into exactly 3 parts (before, sep, after)
print("key=value".partition("="))  # ('key', '=', 'value')
join is called on the separator, not the list

It reads backwards at first: ",".join(parts), not parts.join(","). The separator string owns the method because join must work on any iterable of strings — so the method lives on str.

💡

Use casefold() for case-insensitive comparison, not lower(). casefold handles edge cases like the German ß that lower() misses. For aligning output in tables, zfill/ljust/rjust/center are cleaner than manual spacing.

Validation and alignment methods

Pythonvalidate_align.py
# Validation — all return True/False
print("12345".isdigit())     # True
print("abc123".isalnum())    # True
print("Hello".isalpha())     # True
print("   ".isspace())       # True
print("HELLO".isupper())     # True
print("hello world".islower()) # True

# Alignment / padding
print("5".zfill(3))          # "005"  (zero-fill to width 3)
print("hi".ljust(10, "."))   # "hi........"
print("hi".rjust(10, "."))   # "........hi"
print("hi".center(10, "-"))  # "----hi----"

# Case-insensitive comparison — use casefold, not lower
print("Straße".casefold() == "strasse".casefold())  # True (handles ß)

# Remove a prefix/suffix (Python 3.9+)
print("test_file.py".removesuffix(".py"))    # "test_file"
print("get_name".removeprefix("get_"))       # "name"
Commonly confused
find vs index. Both locate a substring. find returns -1 if not found; index raises ValueError. Use find when "not found" is acceptable; use index when absence is a bug you want to catch.
strip does not remove from the middle. "xxhelloxx".strip("x") gives "hello", but "xhxexllo".strip("x") gives "hxexllo" — it only removes from the ends, stopping at the first non-matching character.
strip takes a set of characters, not a substring. "hello".strip("ho") removes any h or o from the ends, giving "ell" — not the substring "ho".

✅ Intermediate tab complete

  • I can split a string into a list and join a list back into a string
  • I know join is called on the separator: ",".join(parts)
  • I can convert numbers to strings before joining
  • I know removeprefix/removesuffix (3.9+) for clean prefix/suffix removal

Continue to f-strings →

🔴 Expert

Immutability, interning, and PEP 393

What you’ll learn: How CPython stores strings using the smallest unit that fits (PEP 393), string interning, and why building strings with += in a loop is O(n²) while join is O(n).

How to read this tab: Read when optimising text-heavy code or debugging surprising memory usage.

⏱ 20 min📄 1 section🔶 Prerequisite: After Stage 1

Immutability, interning, and the str C implementation

CPython implements str as a variable-length object holding a sequence of Unicode code points. Since PEP 393 (Python 3.3), CPython uses a flexible internal representation that stores each string using the smallest unit that fits all its characters — 1 byte (Latin-1), 2 bytes (UCS-2), or 4 bytes (UCS-4). A pure-ASCII string uses one byte per character; adding a single emoji forces the whole string to 4 bytes per character.

Pythonstr_internals.py
import sys

# PEP 393 — internal size depends on widest character
print(sys.getsizeof("abc"))      # 52 bytes (1 byte/char + header)
print(sys.getsizeof("ab," + "\u00e9"))  # wider — 2 bytes/char
print(sys.getsizeof("ab" + "\U0001F600"))  # widest — 4 bytes/char

# String interning — identical literals may share one object
a = "hello"
b = "hello"
print(a is b)         # True — compile-time interning of identifiers

# But computed strings are not auto-interned
c = "hel" + "lo"      # constant-folded → interned
d = "".join(["h","e","l","l","o"])  # computed → NOT interned
print(c is d)         # False
import sys as _s
print(_s.intern(d) is c)  # True — manual interning forces sharing

Because strings are immutable, building a large string by repeated concatenation in a loop is O(n²) — each += creates a new string and copies all previous characters. The correct pattern is to collect parts in a list and "".join() them once at the end, which is O(n). This is one of the most important performance idioms in Python text processing.

✅ Expert tab complete

  • I know why concatenating in a loop with += is O(n²)
  • I know to build strings with a list + join for O(n) performance
  • I understand PEP 393 flexible string representation at a high level

Continue to f-strings →

Sources

1
Python Standard Library — Text Sequence Type str. docs.python.org/3/library/stdtypes.html#string-methods.
2
Python Standard Library — str.removeprefix/removesuffix (PEP 616, Python 3.9). docs.python.org/3/library/stdtypes.html.
3
PEP 393 — Flexible String Representation. peps.python.org/pep-0393/.
4
Python Language Reference §6.10 — Membership test operations (in). docs.python.org/3/reference/expressions.html.
Source confidence: High Last verified: Primary source: Python stdtypes §str