Strings
Creating, indexing, slicing and formatting text, and the string methods you will use every day.
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.-
inandnot intest 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:
.2fmeans a fixed-point number with two decimals;%shows a percentage;dan integer;bandxbinary 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