Lesson 17 of 34 · 0 of 2 exercises solved

Strings, Deeply

Most real programs are mostly handling: parsing, cleaning, formatting, searching. Python's str type is small, and full of well-named worth knowing by heart.

Strings are sequences, so everything that works on works here: indexing, , len(), in, and iteration. Negative indexes count from the end, and slices never raise IndexError — they just clip.

s = "Hello and welcome"
print(s[0], s[-1])        # H e
print(s[6:9])             # and
print(s[::-1])            # reversed
print(len(s), "welcome" in s)

for word in s.split():
    print(word.upper(), end=" ")
print()
Python (loads on first run)Ctrl+Enter runs

Because strings are immutable, every method returns a new string and leaves the original alone. The methods you will use most: strip, split, join, replace, lower/upper, startswith/endswith, find, and the is* family.

raw = "   Sam Carter  \n"
name = raw.strip()
print(repr(name))

csv_line = "ada,36,london"
fields = csv_line.split(",")
print(fields)
print(" | ".join(fields))

print("programming".replace("gram", "GRAM"))
print("notes.txt".endswith(".txt"), "notes.txt".removesuffix(".txt"))
print("42".isdigit(), "forty".isalpha(), "Hello World".istitle())
print("apple".find("p"), "apple".find("z"))   # 1 -1
Python (loads on first run)Ctrl+Enter runs

are the modern formatting tool. Inside the braces you can put any expression, then a colon and a format spec: width, alignment, padding, precision, thousands separators, and even a date format.

from datetime import date

name, pages, price = "Notebook", 1200, 3.5
print(f"{name:<10}|{pages:>8,}|{price:>8.2f}")
print(f"{name:^12}")          # centred
print(f"{0.256:.1%}")          # 25.6%
print(f"{255:08b} {255:#x}")  # binary and hex
print(f"{date.today():%A, %d %B}")
print(f"{name=} {pages=}")     # debugging shorthand
Python (loads on first run)Ctrl+Enter runs

are not strings. Text is a sequence of Unicode code points; bytes are what goes over the wire or into a file. Convert with encode and decode, and always name the encoding.

text = "Crème brûlée — ☕"
data = text.encode("utf-8")
print(type(data), len(text), len(data))
print(data[:6])
print(data.decode("utf-8") == text)

print(ord("☕"), chr(9749))
Python (loads on first run)Ctrl+Enter runs

Common question

Can a Python string be changed?

A string is an immutable sequence of characters. That is what makes strings safe to share, usable as keys, and easy to reason about: no you call can quietly change your text. The trade-off is that every operation that seems to modify a string actually returns a new one, and you have to keep the result.

Work with strings through their methods (split, join, strip, replace, startswith) and format them with f-strings, whose format specs handle alignment, padding and precision. Build large strings with a and join. At the edges of your program, encode to bytes on the way out and decode on the way in.

Source: The Python data model: "Strings are immutable sequences of Unicode code points."

Common mix-ups

Each of these sounds reasonable. Think about why it is wrong, then open the explanation.

  • name.upper() changes name, since I can print it in upper case afterwards.

  • Building a long string with += in a is efficient because it edits in place.

  • bytes and strings are interchangeable, since both hold text.

Practice

Write normalise_name(raw) that trims whitespace, collapses internal runs of spaces to one, and title-cases the result. " maya CHEN " should become "Maya Chen".

Exercise

Clean a name

3 checks
def normalise_name(raw):
    ...


print(normalise_name("  maya   CHEN "))
 
Python (loads on first run)Ctrl+Enter runs
Output
Press Run to try your code, then Check answer to grade it.

Write receipt(items) that takes a list of (name, quantity, unit_price) and returns a string with one line per item: the name left-aligned in 12 characters, quantity right-aligned in 3, and the line total right-aligned in 8 with two decimals.

Exercise

Aligned columns

2 checks
def receipt(items):
    lines = []
    for name, qty, price in items:
        lines.append(f"{name} {qty} {qty * price}")
    return "\n".join(lines)


print(receipt([("candles", 3, 4.5), ("ink", 12, 0.75)]))
 
Python (loads on first run)Ctrl+Enter runs
Output
Press Run to try your code, then Check answer to grade it.

Check yourself

Quick check

What does "apple"[1:-1] evaluate to?

Finished reading?2 exercises still open. You can come back to them later.

Tip: use the ← and → keys to move between lessons.