6 / 14
Guide Book · Chapter 6

Strings & text

Immutable sequences of Unicode characters: literals, slicing, methods, formatting, and bytes vs text.

Literals

python
a = 'single'
b = "double"
c = """triple quotes
span lines"""
d = r"C:\new\table"          # raw: backslashes stay literal
e = "tab\tnewline\nquote\"end"
print(a, b, c, d, e, sep="\n")
EscapeMeaning
\n \tnewline, tab
\\ \' \"backslash, quotes
\u00e9Unicode code point (é)

Strings are sequences

python
s = "Python"
print(s[0], s[-1], s[1:4], s[::-1], len(s))
print("th" in s, s.count("o"), s.find("z"))   # find returns -1 if missing
for ch in "hey":
    print(ch, ord(ch))

Common methods

Strings are immutable: every method returns a new string.

GroupMethods
caseupper lower title capitalize casefold swapcase
trimstrip lstrip rstrip removeprefix removesuffix
searchfind index count startswith endswith
testisdigit isalpha isalnum isspace isupper
split/joinsplit rsplit splitlines partition join
replacereplace translate
aligncenter ljust rjust zfill
python
line = "  name=Ada, lang=Python  "
clean = line.strip()
pairs = [p.split("=") for p in clean.split(", ")]
print(dict(pairs))
print("report.pdf".removesuffix(".pdf"), "42".zfill(5), "x".center(7, "*"))
print(" ".join(["a", "b", "c"]), "a-b-c".split("-", 1), "k=v=w".partition("="))

Formatting

f-strings are the modern choice. After the : comes a format spec:

python
name, score, ratio = "Ada", 1234.5678, 0.4567
print(f"{name!r:>8} | {score:,.2f} | {ratio:.1%} | {42:08b} | {255:#x}")
print(f"{score=}")                      # self-documenting: score=1234.5678
width = 10
print(f"[{name:^{width}}]")             # nested fields
print("{} is {}".format("pi", 3.14), "%s=%d" % ("x", 5))   # older styles
python
import sys

a = "hello"
b = "hello"
c = "".join(["hel", "lo"])
print(a is b, a is c, a == c)
print(sys.intern(c) is a)
python
import time

t = time.perf_counter()
parts = [str(i) for i in range(100_000)]
text = "".join(parts)
print(len(text), f"{(time.perf_counter() - t) * 1000:.1f} ms")

Text vs bytes

A str is Unicode text; bytes are raw bytes. You encode text to bytes and decode bytes to text.

python
word = "café"
raw = word.encode("utf-8")
print(len(word), len(raw), raw)      # 4 characters, 5 bytes: é takes 2 bytes
print(raw.decode("utf-8"))
print("😀".encode("utf-8"), len("😀"))
python
import sys

print(sys.getsizeof("a" * 100), sys.getsizeof("é" * 100), sys.getsizeof("😀" * 100))

🧭 Scenario: Normalizing user input before comparing: people type " ADA@Example.com ". Use email.strip().casefold() (casefold is a stronger lower() that also handles characters like the German ß) before checking whether it's already registered.

python
inputs = ["  ADA@Example.com ", "ada@example.COM", "Straße", "STRASSE"]
print({s.strip().casefold() for s in inputs})
main.py
Loading editor…
No output yet
Press Run or ⌘↵ to compile and run your code.

Search

Jump to a lesson or a past run