String methods & f-strings
Clean and reshape text with methods, and build strings with f-strings.
Text methods return new strings
Real code rarely gets clean text. User input has stray spaces, CSV columns mix cases, log lines carry delimiters. Normalizing text before you compare it, store it, or use it as a key prevents a whole class of bugs where "Ada", "ada ", and " ADA" get treated as three different users. String methods are the everyday tools for that cleanup.
Start from one fact: a Python string is immutable. Once created, its characters never change. So a string method never edits the value in place. It reads the original and returns a brand-new value, leaving the original untouched. That single property explains everything below.
Common methods. Most return a new string; .split() returns a list. None of them touch the original:
" Hello ".strip() # "Hello" trim surrounding whitespace
"Hello".lower() # "hello"
"Hello".upper() # "HELLO"
"a,b,c".split(",") # ["a", "b", "c"] string -> list
"aca".replace("a", "b") # "bcb" replaces every match, not just the first
| You call | You get back | Type |
|---|---|---|
| ' Hello '.strip() | 'Hello' | str |
| 'Hello'.lower() | 'hello' | str |
| 'a,b,c'.split(',') | ['a', 'b', 'c'] | list of str |
| ','.join(['a', 'b']) | 'a,b' | str, the inverse of split |
| 'aca'.replace('a', 'b') | 'bcb' | str, EVERY match, not just the first |
| 'Hello'.find('z') | -1 | int, and it does not raise |
Because .strip() and .lower() each return a string, you can chain them left to right. The demo below runs messy.strip().lower() on " PyThOn ": .strip() yields "PyThOn", then .lower() turns that into "python".
f-strings build text from values
An f-string drops values straight into { }. Put an f before the opening quote:
name = "Ada"
count = 3
f"{name} has {count} messages" # "Ada has 3 messages"
You can run expressions inside the braces, including method calls. The demo uses f"Hi {name.upper()}!", which evaluates name.upper() to "ADA" and produces "Hi ADA!".
Pitfall: methods do not mutate
Because strings are immutable, this looks like it cleans text but does nothing:
text = " Hello "
text.strip() # returns "Hello", but the result is discarded
print(text) # " Hello " still unchanged
You have to capture the return value: text = text.strip().lower(), or return the chained expression directly. That is exactly the move normalize needs. Forgetting it is the single most common string bug interns ship.
Interview nuance: immutability carries a cost interviewers probe. Building a string with repeated += in a loop is O(n squared), because each concatenation copies the entire string so far into a fresh one. For n pieces that is quadratic work. The fix is "".join(parts), which walks the pieces once for O(n). Reach for str.join over += whenever you assemble text from many parts.
You will now normalize some text by stripping and lowercasing it, then build an uppercased greeting with an f-string.
messy = " PyThOn "
print(messy.strip().lower()) # python
name = "Ada"
print(f"Hi {name.upper()}!") # Hi ADA!Apply
Your turn
The task this lesson builds to.
Implement normalize(text): return text with surrounding whitespace removed and all
letters lowercased.
For " Hello " return "hello".
3 hints and 4 automated checks are waiting in the workspace.
Practice
Make it stick
A second problem on the same idea, so it survives past today.
Implement loud_greeting(name): return an uppercased greeting using an f-string.
For "ada" return "HELLO, ADA!".
2 hints and 3 automated checks are waiting in the workspace.