Creating strings

A string (type str) is a sequence of characters: letters, digits, spaces, punctuation, emoji — any Unicode character. You write a string literal between single quotes or double quotes; both give exactly the same value. Pick the kind that does not appear in the text, so you do not have to escape it.

city = 'Oslo'
quote = "It's raining in Oslo."
reply = 'She said "bring an umbrella".'
empty = ""
print(city, quote, reply)
print(len(empty))
Oslo It's raining in Oslo. She said "bring an umbrella".
0

Triple-quoted strings

Three quotes in a row (""" or ''') start a string that can span several lines. The line breaks become part of the text. Triple-quoted strings are also used for docstrings, see Code Style and Good Habits.

address = """Ada Lovelace
12 St James's Square
London"""
print(address)
Ada Lovelace
12 St James's Square
London

Escape sequences

Inside a string, the backslash (\) starts an escape sequence: a combination that stands for a character that is hard or impossible to type directly. The most common ones:

  • \n — new line
  • \t — tab
  • \\ — one backslash
  • \' and \" — a quote that does not end the string
  • \u20ac — a Unicode character by its code (here €)
print("Line one\nLine two")
print('It\'s a backslash: \\')
print("Price: \u20ac5")
print(len("a\nb"))   # \n is ONE character
Line one
Line two
It's a backslash: \
Price: €5
3

Raw strings

A string with an r prefix is a raw string: backslashes are kept as ordinary characters. That is useful for Windows paths and regular expressions, which contain many backslashes.

print("C:\\new\\temp")    # escaped backslashes
print(r"C:\new\temp")      # raw string: same text, easier to read
print(len(r"\n"))           # a backslash and an n
C:\new\temp
C:\new\temp
2

Indexing and slicing

Indexing

Each character in a string has a position, its index. The first character has index 0, the second 1, and so on. Negative indexes count from the end: -1 is the last character, -2 the one before it. Square brackets pick one character, which is itself a string of length 1.

# Indexes of "Python"
#  P   y   t   h   o   n
#  0   1   2   3   4   5
# -6  -5  -4  -3  -2  -1
word = "Python"
print(word[0], word[5], word[-1], word[-6])
print(len(word))
print(word[len(word) - 1])   # the last index is len - 1
P n n P
6
n

An index outside the string raises an error:

word = "Python"
print(word[6])
IndexError: string index out of range

Slicing

A slice takes a part of a string: s[start:stop] returns the characters from index start up to, but not including, stop. Leave out start to begin at the start; leave out stop to go to the end. A third number, step, takes every n-th character; a negative step walks backward.

word = "Python"
print(word[1:4])     # indexes 1, 2, 3
print(word[:2])      # first two characters
print(word[2:])      # everything from index 2
print(word[-3:])     # last three characters
print(word[::2])     # every second character
print(word[::-1])    # reversed
print(word[4:100])   # slices never raise IndexError
yth
Py
thon
hon
Pto
nohtyP
on

Strings are immutable

Strings are immutable: once a string object exists, its contents cannot change. You cannot replace a character through an index:

word = "Python"
word[0] = "J"
TypeError: 'str' object does not support item assignment

Instead, build a new string and, if you like, bind the same name to it. The old string is not changed; the name simply refers to a new object.

word = "Python"
word = "J" + word[1:]
print(word)
Jython

Integers, floats and tuples are immutable too. Lists and dictionaries are mutable; see Lists and Tuples.

Combining and measuring strings

  • + concatenates (joins) two strings.
  • * with an integer repeats a string.
  • len(s) returns the number of characters.
  • in and not in test for a substring.
first = "Grace"
last = "Hopper"
full = first + " " + last
print(full)
print("-" * 12)
print(len(full))
print("Hop" in full, "hop" in full)
Grace Hopper
------------
12
True False

+ only joins strings with strings: "Room " + 12 raises a TypeError. Convert the number with str(12), or use an f-string.

String methods

A method is a function that belongs to an object, called with a dot: name.upper(). Because strings are immutable, every string method returns a new string (or another value) and leaves the original alone.

Changing case

title = "the art of computer programming"
print(title.upper())
print(title.title())
print(title.capitalize())
print("NASA".lower())
THE ART OF COMPUTER PROGRAMMING
The Art Of Computer Programming
The art of computer programming
nasa

Cleaning, splitting and joining

strip() removes whitespace (spaces, tabs, new lines) from both ends; lstrip() and rstrip() do one side. split() cuts a string into a list of parts: without an argument it splits on any run of whitespace, with an argument on that exact separator. join() does the reverse: it is called on the separator and glues a list of strings together.

email = "  Ada.Lovelace@Example.com \n"
clean = email.strip().lower()
print(clean)
print(clean.split("@"))

print("one  two   three".split())
print("red,green,,blue".split(","))
print("-".join(["2026", "09", "30"]))
print("Tea or coffee?".replace("coffee", "water"))
ada.lovelace@example.com
['ada.lovelace', 'example.com']
['one', 'two', 'three']
['red', 'green', '', 'blue']
2026-09-30
Tea or water?

Searching

find() returns the index of the first match, or -1 if there is none. index() does the same but raises a ValueError when nothing is found. count() counts non-overlapping matches, and startswith() and endswith() test the beginning and end.

fruit = "banana"
print(fruit.find("an"), fruit.find("kiwi"))
print(fruit.count("a"))
print("report.pdf".endswith(".pdf"))
print("https://example.com".startswith("https://"))
1 -1
3
True
True

Testing the content

The is…() methods return True or False and are handy for checking input. isdigit() is true only if the string has at least one character and every character is a digit — so a minus sign or a decimal point makes it false. It also accepts characters such as ² that int() rejects, so to check whether text is a valid number, try int() and catch the ValueError; see Error Handling.

print("2026".isdigit(), "-5".isdigit(), "3.5".isdigit())
print("Oslo".isalpha(), "Oslo 2".isalpha())
print("R2D2".isalnum())
print("   ".isspace(), "ABC".isupper(), "abc".islower())
True False False
True False
True
True True True

f-strings

An f-string (formatted string literal) is a string with an f before the opening quote. Any expression between curly braces is evaluated and its value is inserted into the text. This is the clearest way to combine text with numbers, because no conversion with str() is needed.

name = "Ada"
items = 3
price = 4.5
print(f"{name} ordered {items} items for {items * price} euros.")
print(f"{name.upper()} has {len(name)} letters.")
print(f"{items = }")        # "=" shows the expression and its value
print(f"{{braces}}")        # doubled braces are literal braces
Ada ordered 3 items for 13.5 euros.
ADA has 3 letters.
items = 3
{braces}

Format specifiers

After the expression, a colon starts a format specifier that controls how the value is shown. The most useful parts, in the order they appear:

  • Alignment: < left, > right, ^ center — optionally preceded by a fill character.
  • Width: the minimum number of characters.
  • Thousands separator: , or _.
  • Precision and type: .2f means a fixed-point number with two decimals; % shows a percentage; d an integer; b and x binary and hexadecimal.
price = 1234.5
print(f"{price:.2f}")
print(f"{price:,.2f}")
print(f"{1234567:,}")
print(f"{0.075:.1%}")
print(f"{42:05d}")
print(f"{255:b} {255:x}")
1234.50
1,234.50
1,234,567
7.5%
00042
11111111 ff

Alignment and width

Width and alignment are how you print neat columns. By default, strings are aligned left and numbers right.

print(f"[{'Ada':<8}]")
print(f"[{'Ada':>8}]")
print(f"[{'Ada':^8}]")
print(f"[{'Ada':*^9}]")

for product, cost in [("Coffee", 3.5), ("Croissant", 2.25)]:
    print(f"{product:<12}{cost:>6.2f}")
[Ada     ]
[     Ada]
[  Ada   ]
[***Ada***]
Coffee        3.50
Croissant     2.25

Since Python 3.12, the expression inside the braces may reuse the quote character of the f-string itself. In older versions you had to use the other kind of quote, as in the examples above.

names = ["Ada", "Grace", "Linus"]
print(f"Team: {", ".join(names)}")
Team: Ada, Grace, Linus

On Python 3.11 and older, that line stops with SyntaxError: f-string: expecting '}'. Use the other kind of quote inside the braces, and the code runs on every version:

names = ["Ada", "Grace", "Linus"]
print(f"Team: {', '.join(names)}")
Team: Ada, Grace, Linus

Unicode and comparing strings

Characters and code points

Python strings are Unicode: every character has a number, its code point. ord() returns the code point of a character, and chr() returns the character for a code point. len() counts code points, not bytes. That is usually one per character, so "café" has length 4, but some emoji and letters built from combining marks count as more than one. How characters become bytes on disk is a question of encoding, covered in Files and Paths.

print(ord("A"), ord("a"), ord("€"))
print(chr(65), chr(8364))
print(len("café"))
65 97 8364
A €
4

Comparing strings

== and != compare strings exactly, including case and spaces. < and > compare them character by character, by code point — "alphabetical order" only as long as all letters have the same case. Every uppercase ASCII letter (A–Z) comes before every lowercase one, and digits in text are compared as characters, not numbers.

print("apple" < "banana")
print("Zebra" < "apple")     # "Z" is 90, "a" is 97
print("10" < "9")            # "1" comes before "9"
print("Oslo" == "oslo", "Oslo".lower() == "oslo")
True
True
True
False True