PYTHON / STRINGS
Essential string methods
Clean, normalize, inspect and pad strings using the core str methods: strip, case conversion, the is* tests, and zfill/ljust/rjust/center.
What you will learn
- Chain methods like raw.strip().casefold() and assign the result; the original is unchanged
- Use strip/lstrip/rstrip for characters, removeprefix/removesuffix for exact substrings
- Read is* methods as yes/no questions; the empty string answers False to all of them
- Pad and align with zfill, ljust, rjust and center instead of counting spaces by hand
Understanding Essential string methods
A string method is a function that belongs to the str type, so you can call it on anything that is a string: a variable, a literal like "abc".upper(), or the value another method just returned. Every one of them either builds a brand-new string or returns a bool; none of them modify the object they were called on, because str values cannot be changed after creation. That is why a line containing only name.strip() is useless: the trimmed string is built and immediately discarded, and name still holds the spaces.
There are around forty of these methods, so it pays to remember them as families rather than as a list. Case conversion: upper, lower, title, capitalize, swapcase, casefold. Trimming: strip, lstrip, rstrip, plus removeprefix and removesuffix. Yes/no questions: isdigit, isdecimal, isalpha, isalnum, isspace, isupper, isidentifier. Width control: zfill, ljust, rjust, center. Once you know which family you need, the exact name is easy to guess and easy to confirm with dir(str).
Two details cause most of the confusion. First, the argument to strip is a set of characters to shave off, not a suffix: "banana".strip("ban") returns an empty string because every character is in that set. Second, casefold is the aggressive normalizer meant for comparisons, so "ß".casefold() gives "ss" while "ß".lower() leaves it alone; use casefold on both sides when you compare user input case-insensitively.
raw = "\t ada LOVELACE \n"
clean = raw.strip() # trims whitespace at both ends, returns a new string
print(repr(clean))
print(clean.title()) # first letter of each word up, the rest down
print(clean.upper())
print(clean.casefold() == "ada lovelace")
print(len(raw), len(clean)) # raw itself was never touched
code = "42"
print(code.isdigit(), code.zfill(5))
print("42a".isdigit())String methods never edit the string in place: they hand back a new string or a bool, so the return value is the whole point.
Worked examples
Trimming characters vs trimming text
Shows that strip works on a character set while removeprefix/removesuffix remove one exact piece of text.
path = "///reports/2024/summary.csv///"
print(path.strip("/"))
print(path.lstrip("/"))
name = "test_report.csv"
print(name.removesuffix(".csv"))
print(name.removeprefix("test_"))
print(repr("banana".strip("ban")))Example explained
Line 1strip("/") shaves every leading and trailing slash because "/" is read as a set of one character.
Line 2lstrip only works on the left end, so the three trailing slashes survive.
Line 3removesuffix(".csv") removes that exact text once, and returns the string unchanged when the suffix is absent.
Line 4"banana".strip("ban") ends up empty: every character is in {b, a, n}, which proves the argument is not a suffix.
Validating input with the is* tests
Compares the boolean character-class methods on typical values, including the empty string and a superscript digit.
for s in ["", "2024", "v2", " ", "Ada"]:
print(repr(s), s.isdigit(), s.isalpha(), s.isspace(), s.isidentifier())
print("\u00b2".isdigit(), "\u00b2".isdecimal())Example explained
Line 1The empty string answers False to all four tests, which is convenient: "" is never accepted as a number or a name.
Line 2"v2" fails both isdigit and isalpha because those need every character to be of one class, but it passes isidentifier.
Line 3" ".isspace() is True, so trim first if you do not want blank input to look meaningful.
Line 4'\u00b2' (superscript two) is a digit but not a decimal, so use isdecimal when you intend to call int() afterwards.
Aligning a small report
Uses ljust, rjust and center to build fixed-width columns without manual space arithmetic.
rows = [("apples", 3), ("kiwi", 12), ("watermelon", 1)]
print("item".ljust(12) + "qty".rjust(4))
print("-" * 16)
for item, qty in rows:
print(item.ljust(12) + str(qty).rjust(4))
print("totals".center(16, "."))Example explained
Line 1ljust(12) pads on the right up to 12 characters, so the item column starts at the same place on every line.
Line 2rjust(4) pads on the left, which lines up the numbers by their last digit.
Line 3str(qty) is required because rjust is a string method and integers do not have it.
Line 4center takes an optional fill character, here ".", instead of the default space.
Important notes
removeprefix and removesuffix were added in Python 3.9; on older versions use text[len(prefix):] guarded by startswith.
capitalize() lowercases everything after the first character, and title() capitalizes after any non-letter, so "don't".title() gives "Don'T".
Common mistakes
Writing name.upper() on its own line and expecting name to change; strings are immutable, so the uppercase copy is discarded and the old value is printed later.
Using strip to drop an extension: "cases.csv".strip(".csv") returns "ase", because it keeps eating any of the characters . c s v from both ends.
Validating numbers with isdigit: "-3".isdigit() and "3.5".isdigit() are both False, so valid input is rejected, while a superscript like '\u00b2' passes and then crashes int().
Try it yourself
Change, predict, then run
Start from entry = "\t Login: AdaL42 \n", strip the surrounding whitespace, remove the "Login: " prefix, then print the username in lowercase and print whether it is alphanumeric with isalnum().
Open the Python workspaceCheck your understanding
What does "mississippi".strip("mip") return?
- 'ssissi'
- 'ssissippi'
- 'ssiss'
- 'mississippi'
Show answer
strip walks inward from each end and removes any character that appears in "mip", stopping at the first character that does not. From the left it drops 'm' and 'i' and halts at 's'; from the right it drops 'i', 'p', 'p' and then the next 'i' too, halting at 's', leaving 'ssiss'. 'ssissi' is the tempting answer if you assume only the trailing group 'ppi' is removed, but strip does not work on substrings and keeps going past it.