The idea
Real-world text is messy. Customer names arrive as " ayu LESTARI ", cities as "jakarta", "Jakarta " and "JAKARTA", and a whole row of data might come as one long string like "Ayu;Jakarta;285000". Before you can count, group or compare anything, you have to clean it.
Python strings come with dozens of built-in methods: functions that belong to a value and are called with a dot, like name.upper(). This module covers the ones you'll use every week.
Methods return new strings
Remember that strings are immutable: they can't be changed in place. So a string method never changes the original; it returns a new string:
name = "ayu lestari"
name.upper()
print(name)
shout = name.upper()
print(shout)
ayu lestari
AYU LESTARI
The second line computed "AYU LESTARI" and then threw it away, because nothing kept the result. This is the most common string bug of all.
name.strip() on its own line does nothing useful. Keep the result: name = name.strip().
Changing case
The same city can arrive as jakarta, Jakarta or JAKARTA depending on who typed it. To a person those are obviously the same place, but to Python they're three different strings, so a count of customers per city would show three separate Jakartas. These methods give you a string in one consistent style of capitals:
city = "jaKarTA"
print(city.upper())
print(city.lower())
print(city.title())
print("budi santoso".capitalize())
JAKARTA
jakarta
Jakarta
Budi santoso
.title() capitalises the first letter of every word, while .capitalize() capitalises only the first letter of the whole string. Converting to one case with .lower() is the standard trick before comparing text, so "Jakarta", "JAKARTA" and "jakarta" all match.
Trimming whitespace with strip
Whitespace means spaces, tabs and newlines. It sneaks in from forms, spreadsheets and copy-pasting, and it's invisible, which makes it dangerous: "Jakarta " is not equal to "Jakarta".
raw = " Jakarta \n"
print(f"[{raw.strip()}]")
print(f"[{raw.lstrip()}]")
print(f"[{raw.rstrip()}]")
[Jakarta]
[Jakarta
]
[ Jakarta]
.strip() removes whitespace from both ends, .lstrip() only from the left, .rstrip() only from the right. Whitespace in the middle stays. You can also strip specific characters: "***SALE***".strip("*") gives "SALE".
Finding and replacing
Once text is clean, you'll often need to ask questions about it. Does this delivery note mention Jakarta? How many times? Does the product code start with the right prefix? And sometimes you need to swap one word for another everywhere, like when a warehouse moves to a new city. Python has a method for each of these:
note = "Ship to Jakarta. Jakarta warehouse only."
print(note.replace("Jakarta", "Bandung"))
print(note.count("Jakarta"))
print(note.find("warehouse"))
print("Jakarta" in note)
print(note.startswith("Ship"), note.endswith("."))
Ship to Bandung. Bandung warehouse only.
2
25
True
True True
Going through the output line by line:
.replace(old, new)replaces every occurrence, not just the first, which is why both Jakartas became Bandung..count(text)counts occurrences..find(text)gives the index wheretextfirst appears, or-1if it isn't there.- The
inoperator answers "is this text anywhere inside?" withTrueorFalse. It's usually the clearest way to check. .startswith()and.endswith()check the beginning and end.
Splitting text into pieces
.split() cuts a string into a list of smaller strings. You'll learn lists properly soon; for now, think of a list as an ordered collection written with square brackets.
row = "Ayu Lestari;Jakarta;Consumer;285000"
parts = row.split(";")
print(parts)
print(parts[0])
print(parts[3])
['Ayu Lestari', 'Jakarta', 'Consumer', '285000']
Ayu Lestari
285000
The argument is the separator: the text to cut on. The separator itself disappears. With no argument, .split() splits on any run of whitespace and ignores extra spaces, which is perfect for messy sentences:
print(" Arabica Gayo 250g ".split())
['Arabica', 'Gayo', '250g']
Notice that parts[3] is the string "285000", not a number. Splitting text always gives text back; you'll convert it with int() in the next module.
Joining pieces back together
.join() is the opposite of split: it glues a list of strings together, with the string you call it on placed between each piece:
cities = ["Jakarta", "Bandung", "Surabaya"]
print(", ".join(cities))
print(" | ".join(cities))
print("-".join("2024 10 05".split()))
Jakarta, Bandung, Surabaya
Jakarta | Bandung | Surabaya
2024-10-05
The syntax looks backwards at first: the separator comes first, then .join(list). Read ", ".join(cities) as "join the cities with comma-space".
Chaining methods
Because each method returns a new string, you can call another method on the result straight away. This is called chaining, and it reads left to right like a recipe:
raw_name = " aYU lestari "
clean = " ".join(raw_name.split()).title()
print(f"[{clean}]")
[Ayu Lestari]
Step by step: .split() breaks it into words (dropping all the extra spaces), " ".join(...) puts the words back with single spaces, and .title() fixes the capitals. This exact pattern cleans thousands of names in real projects.
Why this matters for clean code
Text cleaning is where data bugs hide: two "different" customers who are really "Ayu" and "Ayu ". Clean your text once, as early as possible, with a clear chain of methods, and store the cleaned value. Short chains read well; if one grows beyond three or four steps, split it over several lines with good variable names so each step is visible.
Recap
- String methods return new strings. Always keep the result:
name = name.strip(). - Case:
.upper(),.lower(),.title(),.capitalize(). Use.lower()before comparing. - Whitespace:
.strip(),.lstrip(),.rstrip(). - Search:
in,.find(),.count(),.startswith(),.endswith(). Replace with.replace(old, new). .split(sep)turns a string into a list;sep.join(list)turns a list into a string.- Chain methods to clean text in one readable line.