PythonMastery
reference 5 min read · lesson 2 of 25 in Reference

Python String Methods Cheat Sheet

1 · The lesson

read

A 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.

python
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.

python
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.

MethodWhat it doesExampleReturns
sub in sIs 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
python
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.

MethodExampleReturns
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'
python
"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.

python
"  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():

python
"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.

MethodExampleReturns
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'
python
", ".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.

python
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.

python
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.

python
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.

python
for ch in "Ada":
    print(ch)
python
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')
python
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

python
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):

python
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:

python
"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:

python
"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:

python
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.in

Short 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.