Python String Methods Cheat Sheet
1 · The lesson
readA string is a piece of text, such as a name, a file path or a line from a file. This page lists the string tools you will use most often, with an example you can run for each one. A string never changes after you create it, so every method gives you a new string and you must keep the result: s = s.strip(). For the full tutorial, see Strings.
1. Create a string
Single quotes and double quotes make the same kind of string. Triple quotes let one string run over several lines. Put r before the quotes to make a raw string: Python then keeps every backslash exactly as you typed it, which is useful for Windows paths and regular expressions.
a = 'single' b = "double" print(a == 'single', "hi" == 'hi') # True True letter = """Dear Ada, Thanks for the report.""" # the line break is kept path = r"C:\Users\new\data" # raw string: the backslashes stay "py" + "thon" # 'python' (+ joins two strings) "ab" * 3 # 'ababab' (* repeats a string) str(42) # '42' (turns any value into text)
2. Index and slice
Each character has a position number, called an index. The first character is at index 0, and negative numbers count from the end. A slice s[start:stop] takes the characters from start up to, but not including, stop.
s = "python" s[0] # 'p' (the first character) s[-1] # 'n' (the last character) s[1:4] # 'yth' (index 1, 2 and 3; index 4 is not included) s[:3] # 'pyt' (from the start, up to index 3) s[3:] # 'hon' (from index 3 to the end) s[::2] # 'pto' (every second character) s[::-1] # 'nohtyp' (the string reversed) len(s) # 6
The Slicing cheat sheet explains slices in more detail.
3. Search and test
find() returns the index of the first match, or -1 when the text is not there. index() does the same search but raises a ValueError when it finds nothing. The is...() methods check what kind of characters a string contains.
| Method | What it does | Example | Returns |
|---|---|---|---|
sub in s | Is the text inside the string? | "th" in "python" | True |
s.count(sub) | How many times the text appears | "banana".count("a") | 3 |
s.find(sub) | Index of the first match, or -1 | "hello".find("l") | 2 |
s.rfind(sub) | Index of the last match, or -1 | "hello".rfind("l") | 3 |
s.index(sub) | Like find(), but raises an error if not found | "hello".index("z") | ValueError |
s.startswith(p) | Does the string begin with p? | "file.py".startswith("file") | True |
s.endswith(p) | Does the string end with p? | "file.py".endswith(".py") | True |
s.isdigit() | Are all characters the digits 0-9? | "2026".isdigit() | True |
s.isalpha() | Are all characters letters? | "abc".isalpha() | True |
s.isalnum() | Are all characters letters or digits? | "a1".isalnum() | True |
s.isspace() | Are all characters spaces, tabs or new lines? | " \t".isspace() | True |
s.find("o") # 4 s.find("z") # -1 (not found) "a.csv".endswith((".csv", ".tsv")) # True (a tuple of endings tests several endings at once)
setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) s = _AutoMock('s') # Earlier blocks on this page that this one builds on, re-run quietly first. _pm_earlier = [ 's = "python"\ns[0] # \'p\' (the first character)\ns[-1] # \'n\' (the last character)\ns[1:4] # \'yth\' (index 1, 2 and 3; index 4 is not included)\ns[:3] # \'pyt\' (from the start, up to index 3)\ns[3:] # \'hon\' (from index 3 to the end)\ns[::2] # \'pto\' (every second character)\ns[::-1] # \'nohtyp\' (the string reversed)\nlen(s) # 6', ] def _pm_run_earlier(_srcs, _g): import sys as _s, io as _io, warnings as _w for _src in _srcs: _o, _e = _s.stdout, _s.stderr _s.stdout = _s.stderr = _io.StringIO() try: with _w.catch_warnings(): _w.simplefilter('ignore') exec(compile(_src, '<earlier block>', 'exec'), _g) except (Exception, SystemExit): pass finally: _s.stdout, _s.stderr = _o, _e if 'matplotlib.pyplot' in _s.modules: _s.modules['matplotlib.pyplot'].close('all') # their plots belong to their own blocks _pm_run_earlier(_pm_earlier, globals()) del _pm_earlier, _pm_run_earlier
4. Change the case
casefold() works like lower(), but it also changes special letters, such as the German ß to ss. Use casefold() when you compare two pieces of text, not when you show text to a reader.
| Method | Example | Returns |
|---|---|---|
s.upper() | "Hi".upper() | 'HI' |
s.lower() | "Hi".lower() | 'hi' |
s.title() | "hi there".title() | 'Hi There' |
s.capitalize() | "hi there".capitalize() | 'Hi there' |
s.swapcase() | "Hi There".swapcase() | 'hI tHERE' |
s.casefold() | "Straße".casefold() | 'strasse' |
"Straße".casefold() == "STRASSE".casefold() # True
5. Clean up text
strip() removes spaces, tabs and new lines from both ends. lstrip() works on the left end only, and rstrip() on the right end only. If you give strip() some characters, it removes any of those characters from the ends.
" hi \n".strip() # 'hi' " hi ".lstrip() # 'hi ' " hi ".rstrip() # ' hi' "--hi--".strip("-") # 'hi' "report.csv".removesuffix(".csv") # 'report' (Python 3.9 and later) "v1.2".removeprefix("v") # '1.2' "a-b-c".replace("-", " ") # 'a b c' "a-b-c".replace("-", "", 1) # 'ab-c' (the 1 means: replace only the first match)
translate() changes or deletes single characters, using a table made by str.maketrans():
"hello".translate(str.maketrans("aeiou", "AEIOU")) # 'hEllO' "hello".translate(str.maketrans("", "", "aeiou")) # 'hll' (the third argument lists characters to delete)
6. Split and join
split() cuts a string into a list of parts. join() does the opposite: it joins a list of strings into one string. You call join() on the separator.
| Method | Example | Returns |
|---|---|---|
s.split(sep) | "a,b,c".split(",") | ['a', 'b', 'c'] |
s.split() | "a b\tc".split() | ['a', 'b', 'c'] (splits on any spaces or tabs) |
s.split(sep, n) | "k=v=w".split("=", 1) | ['k', 'v=w'] (split at most once) |
s.rsplit(sep, n) | "a b c".rsplit(" ", 1) | ['a b', 'c'] (splits once, starting from the right) |
s.splitlines() | "one\ntwo".splitlines() | ['one', 'two'] |
s.partition(sep) | "key=val".partition("=") | ('key', '=', 'val') |
sep.join(items) | ", ".join(["a", "b"]) | 'a, b' |
", ".join(["Ada", "Grace"]) # 'Ada, Grace' "-".join(str(n) for n in [1, 2, 3]) # '1-2-3' (join() needs strings, so convert numbers first)
7. Format with f-strings
Put f before the quotes and write any value or expression inside {}. After a colon you can add a format spec: a short code that says how to show the value.
name, pi, big, rate = "Ada", 3.14159, 1234567, 0.256 f"Hi {name}!" # 'Hi Ada!' f"{pi:.2f}" # '3.14' (rounds to 2 decimal places) f"{big:,}" # '1,234,567' (a comma between thousands) f"{rate:.1%}" # '25.6%' (a percentage with 1 decimal place) f"{7:03d}" # '007' (pad with zeros to 3 digits) f"{name:>6}" # ' Ada' (right-align in 6 characters; < is left, ^ is centre) f"{name:*^7}" # '**Ada**' (centre the name and fill the space with *) f"{pi=:.1f}" # 'pi=3.1' (= also shows the name, which helps when you debug) f"{255:x}" # 'ff' (255 written in hexadecimal; b gives binary)
Older code uses "{} is {}".format(name, 36) or "%s is %d" % (name, 36). Both still work, but f-strings are easier to read. The f-strings cheat sheet lists every format spec.
8. Convert to and from text
Bytes are the raw numbers a computer stores for text. encode() turns a string into bytes (UTF-8 by default) and decode() turns bytes back into a string.
int("42") # 42 float("3.5") # 3.5 list("abc") # ['a', 'b', 'c'] ord("A") # 65 (the character's code number) chr(97) # 'a' (the character for a code number) "café".encode() # b'caf\xc3\xa9' b"hi".decode() # 'hi' str(7).zfill(4) # '0007' (pad a number with zeros on the left)
9. Escape sequences
A backslash starts an escape sequence: two or more characters that stand for one special character.
len("a\nb") # 3 (\n is one character: a new line) print("tab\there") # \t is a tab print("C:\\data") # \\ is one backslash "It's" # "It's" (double quotes let you use ' inside) 'It\'s' # "It's" (or escape the quote) "caf\u00e9" # 'café' (\u and 4 hexadecimal digits give any character)
10. Loop over text
A for loop over a string gives you one character at a time.
for ch in "Ada": print(ch)
A d a
setup added so this can run · defines A, d, a
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) A = _AutoMock('A') d = _AutoMock('d') a = _AutoMock('a')
s = "python" [i for i, ch in enumerate(s) if ch == "o"] # [4] (every index where "o" appears) "".join(sorted("cab")) # 'abc' sorted(set("banana")) # ['a', 'b', 'n'] (each different character, once) max(["fig", "apple"], key=len) # 'apple' (the longest word) sorted(["b", "A", "c"], key=str.lower) # ['A', 'b', 'c'] (sort without caring about case) " ".join(w.capitalize() for w in "ada lovelace".split()) # 'Ada Lovelace'
11. Useful tools in the standard library
import string, textwrap textwrap.shorten("A long title here", 12) # 'A long [...]' (shortens to 12 characters, cutting at a space) string.ascii_lowercase[:5] # 'abcde' string.digits # '0123456789'
Common mistakes
Trying to change one character. s[0] = "P" raises TypeError: 'str' object does not support item assignment, because a string cannot change. Build a new string instead (full error page):
s = "python" s = "P" + s[1:] s # 'Python'
Calling a method and not keeping the result. s.upper() returns a new string and leaves s as it was. Write s = s.upper().
Using strip() to remove a word. strip() removes characters, in any order, not a word:
"www.website.com".strip("w.") # 'ebsite.com' (the w of website is gone too) "www.website.com".removeprefix("www.") # 'website.com'
Comparing numbers stored as text. Strings compare one character at a time, so "10" < "9" is True. Convert first: int("10") < int("9") is False.
Adding a number to a string. "Total: " + 5 raises TypeError: can only concatenate str (not "int") to str. Write f"Total: {5}" or "Total: " + str(5) (full error page).
title() and apostrophes. title() puts a capital letter after any character that is not a letter:
"o'neil's".title() # "O'Neil'S"
Searching with index(). "hello".index("z") raises ValueError: substring not found. Use find(), which returns -1, or check with in first.
Building a long string with += in a loop. Each += makes a new string, which is slow for thousands of pieces. Collect the pieces in a list and join them once:
pieces = [] for n in range(3): pieces.append(f"line {n}") "\n".join(pieces) # 'line 0\nline 1\nline 2'
See also
Practice this
on practicepython.inShort exercises that run in your browser and tell you what your code did, as well as whether a test passed.
Found this useful? Share it with a friend who’s learning Python.