The idea
So much of a data analyst's work is text: names, cities, product codes, email addresses, messages in a report. In Python, text is a string (str), a sequence of characters between quotes. This module covers how to build strings, pull pieces out of them, and, most usefully, how to drop values into a sentence cleanly with f-strings.
Quotes, and when to use which
Python needs to know where a piece of text starts and ends, and the quotes are how you tell it. Single and double quotes make exactly the same kind of string, so the choice only matters when the text itself contains a quote. If a customer's name has an apostrophe, like "Ayu's order", wrapping it in single quotes would end the string right after Ayu. So pick whichever kind doesn't clash with the text inside:
shop = "Toko Kita"
message = "Ayu's order has shipped"
html = '<p class="note">Hi</p>'
print(message)
print(html)
Ayu's order has shipped
<p class="note">Hi</p>
Sometimes switching quotes isn't enough, because the text has both kinds, or you need something you can't easily type, like a line break in the middle of a message. For those cases there are escape sequences: a backslash followed by a character, which together stand for one special character.
| Escape | Means |
|---|---|
\n | new line |
\t | tab |
\' or \" | a quote that doesn't end the string |
\\ | a single backslash |
print("Line one\nLine two")
print("Name:\tAyu")
Line one
Line two
Name: Ayu
For text that spans several lines, use triple quotes, which keep the line breaks exactly as you typed them:
note = """Dear customer,
Your order is on its way.
Toko Kita"""
print(note)
Dear customer,
Your order is on its way.
Toko Kita
Combining strings
You'll often have the pieces of a piece of text in separate variables, like a customer's first and last name, and need to put them together. + joins strings end to end (this is called concatenation), and * repeats a string a number of times, which is handy for drawing a divider line in a printed report:
first = "Ayu"
last = "Lestari"
full_name = first + " " + last
print(full_name)
print("-" * 20)
print(len(full_name))
Ayu Lestari
--------------------
11
len() gives the length of a string: the number of characters, spaces included.
+ only joins strings to strings. Mixing in a number is a very common error:
items = 3
print("Items: " + items)
TypeError: can only concatenate str (not "int") to str
You could fix it with str(items), which converts the number to text. But there's a much better way, coming up next.
f-strings: values inside text
An f-string is a string with the letter f right before the opening quote. Inside it, anything in curly braces { } is worked out as Python code and inserted into the text:
name = "Ayu"
items = 3
total = 285000
print(f"{name} bought {items} items for Rp {total}")
Ayu bought 3 items for Rp 285000
No +, no str(), no forgotten spaces. The braces can hold any expression, not just a variable:
price = 95000
quantity = 3
print(f"Subtotal: {price * quantity}")
print(f"Name in capitals: {name.upper()}")
Subtotal: 285000
Name in capitals: AYU
Formatting numbers
After the expression, a colon : starts a format specification that controls how the value looks. These four cover most reports:
total = 1310000
rate = 0.112
average = 262000 / 3
print(f"{total:,}") # thousands separators
print(f"{average:.2f}") # 2 decimal places
print(f"{rate:.1%}") # as a percentage, 1 decimal
print(f"[{'Kopi':<8}]") # left-align in 8 characters
print(f"[{'Kopi':>8}]") # right-align in 8 characters
1,310,000
87333.33
11.2%
[Kopi ]
[ Kopi]
You can combine them too: f"{average:,.2f}" gives 87,333.33. Alignment is handy for printing tidy text tables, as you'll see in the questions.
Inside an f-string, use the other kind of quote for strings in the braces, like f"[{'Kopi':<8}]" above. Using the same quote would end the f-string too early.
Indexing and slicing
Product codes, order numbers and dates often pack several pieces of information into one string. In TK-2024-0042, the first two letters are the shop, the middle is the year, and the end is the order number. To get at those pieces, you need to be able to point at specific characters.
A string is a sequence of characters, so each character has a position, called its index. The one thing to get used to is that Python starts counting from 0, not 1:
code = "TK-2024-0042"
print(code[0]) # first character
print(code[3]) # fourth character
print(code[-1]) # last character
print(code[-4:]) # last four characters
print(code[3:7]) # from index 3 up to (not including) 7
T
2
2
0042
2024
code[0]is the first character. Negative indexes count from the end:-1is the last.- A slice
code[start:stop]gives the characters fromstartup to, but not including,stop. That's whycode[3:7]is four characters long: 7 − 3 = 4. - Leave out
startto begin at the start, orstopto go to the end:code[:2]is"TK",code[8:]is"0042".
Strings are immutable: you can't change a character in place. code[0] = "X" raises a TypeError. Instead, build a new string: "X" + code[1:].
Why this matters for clean code
f-strings are the modern, readable way to build text in Python. Compare "Total: " + str(total) + " (" + str(items) + " items)" with f"Total: {total} ({items} items)": the second one shows you exactly what the output looks like. Clean code makes the result visible in the source, and f-strings do exactly that.
Recap
- Strings use single, double or triple quotes. Escapes like
\nadd special characters. +joins strings,*repeats them,len()counts characters. You can't+a string and a number.- f-strings:
f"Hello {name}"puts values (or any expression) into text. - Format specs:
{x:,}separators,{x:.2f}decimals,{x:.1%}percentages,{x:<10}/{x:>10}alignment. - Index from 0, negative indexes from the end.
s[start:stop]slices up to but not includingstop. - Strings are immutable; you build new ones instead of changing them.