Strings & String Formatting

Python Fundamentals — Strings & String Formatting
Python Fundamentals
Course 1 · Chapter 5 · Strings & String Formatting

🔤 Strings & String Formatting

You've been using strings since Chapter 1 without a close look at what they can do. This chapter covers indexing and slicing, string immutability, the most common string methods, and Python's three ways to build formatted strings — f-strings, .format(), and old-style % — with a clear recommendation for which one to actually reach for.

✂️ String Indexing & Slicing

word = "Python" print(word[0]) # P — first character print(word[-1]) # n — last character, negative index print(word[1:4]) # yth — slice: start inclusive, stop exclusive print(word[:3]) # Pyt — omit start, defaults to 0 print(word[3:]) # hon — omit stop, defaults to the end print(word[::-1]) # nohtyP — step of -1 reverses the string

Slice syntax is [start:stop:step] — the same shape you'll see again on lists in Chapter 6. stop is exclusive, matching range() from the last chapter.

String Indexing: Go vs Kotlin vs Python

LanguageIndexing a string
GoA string is a byte slice — indexing with s[0] gives a raw byte, not a character. Multi-byte UTF-8 characters (like emoji or accented letters) require iterating with range to get correct character boundaries.
Kotlins[0] gives a Char — indexing is character-based like Python, inherited from Java's String behavior.
Pythons[0] gives a single-character string, always Unicode-aware — no separate "byte vs character" distinction to worry about at this level.

🔒 Strings Are Immutable

A string can't be changed in place — every string method that looks like it's "modifying" a string is actually returning a brand-new string:

name = "python" upper_name = name.upper() print(name) # python — unchanged print(upper_name) # PYTHON — a new string

🛠️ Common String Methods

s = " Hello, World " s.strip() # "Hello, World" — removes leading/trailing whitespace s.lower() # " hello, world " s.upper() # " HELLO, WORLD " s.strip().split(", ") # ['Hello', 'World'] "-".join(["a", "b", "c"]) # "a-b-c" s.replace("World", "Python") # " Hello, Python " s.strip().startswith("Hello") # True s.strip().endswith("World") # True s.find("World") # 9 — index where it starts, or -1 if not found
💡 join() Lives on the Separator, Not the List

"-".join(["a", "b", "c"]) reads backwards to most newcomers — the separator string comes first, and the list of pieces to join is the argument. Building a string by repeatedly concatenating with + inside a loop works, but "".join(...) is the idiomatic and more efficient way to combine many pieces at once, since strings are immutable and each + creates yet another new string.

📝 f-strings: Formatted String Literals

An f-string embeds expressions directly inside a string, prefixed with f:

name = "Ada" age = 28 print(f"{name} is {age} years old") # Ada is 28 years old print(f"Next year: {age + 1}") # expressions work directly inside {} # Next year: 29 pi = 3.14159265 print(f"Pi rounded: {pi:.2f}") # format spec after the colon # Pi rounded: 3.14

📐 .format() and % — The Older Styles

# .format() — pre-f-string standard, still common in older code print("{} is {} years old".format(name, age)) # % formatting — the oldest style, inherited from C's printf print("%s is %d years old" % (name, age))

Which Style Should You Use?

f-strings (added in Python 3.6) are the modern, idiomatic choice — they're more readable since the variable sits directly inside the string instead of matched up positionally, and they're generally faster. .format() and % both still appear constantly in real-world and older code, so recognizing them matters even though you should default to f-strings in new code you write.

Slicing

s[start:stop:step] — stop is exclusive, negative indices count from the end.

Immutability

String methods never modify in place — they always return a new string.

String Methods

.strip(), .split(), .join(), .replace(), .find() and more.

f-strings

f"{expr:.2f}" — the modern, idiomatic way to build formatted strings.

💻 Coding Challenges

Challenge 1: Reverse Words

Given the string "Python is fun", use .split() and .join() to print the words in reverse order: "fun is Python".

Goal: Practice combining .split() and .join() with slicing to reverse a sequence.

→ Solution

Challenge 2: Formatted Receipt Line

Given item = "Coffee", price = 4.5, and qty = 3, use an f-string to print a line like "3x Coffee: $13.50", with the total formatted to exactly 2 decimal places.

Goal: Practice f-string expressions and the :.2f format spec together.

→ Solution

Challenge 3: Palindrome Check

Write code that checks whether the string "racecar" is a palindrome (reads the same forwards and backwards), using slicing rather than a loop.

Goal: Practice using the [::-1] slice pattern to solve a real small problem.

→ Solution

🎯 What's Next

Next chapter: Lists, Tuples & Sets — mutable vs. immutable sequences, and a first look at comprehensions.