Numbers, Text & Lists
Use Python as a calculator, slice strings like a pro, meet the list, and write your first loop. Along the way, find out why 0.1 + 0.2 is not 0.3.
You will learn
- Integer and float arithmetic, including
/,//,%and**. - Why floating-point numbers are slightly inexact, and what to do about it.
- Strings: quotes, escapes, raw strings, indexing, slicing and immutability.
- Lists: indexing, slicing, changing items, and the "two names, one list" trap.
- Multiple assignment,
whileloops, andprint()options.
Numbers
The REPL works like a calculator. Type an expression and it shows the value. + - * / work as you expect, and parentheses group.
Python has two main number types:
int: whole numbers like2,-7,1_000_000(underscores are allowed for readability). Aninthas no maximum size.float: numbers with a fractional part, like5.0and1.6. Like Java'sdouble.
Four kinds of division-ish operators
| Operator | Name | Example | Result |
|---|---|---|---|
/ | true division (always a float) | 17 / 3 | 5.666666666666667 |
// | floor division (rounds down) | 17 // 3 | 5 |
% | remainder (modulo) | 17 % 3 | 2 |
** | power | 2 ** 7 | 128 |
☕ Java / 🟨 JS: in Java, 17 / 3 is 5 (integer division). In Python it is 5.666…. Use // when you want Java's behaviour. There is no ++ or -- in Python: write x += 1. Unlike JS, int and float are different types.
⚠️ Pitfall: negatives round toward minus infinity. // rounds down, not toward zero. The sign of % follows the divisor. Java and JS do it the other way.
Precedence: ** binds tighter than unary minus
Variables and mixed types
= gives a value a name. Using a name that was never assigned is an error. Mixing int and float gives a float.
Handy built-ins: abs(-3) is 3, round(3.7) is 4, int(3.9) is 3 (it truncates toward zero), float("2.5") is 2.5. Python also has complex numbers (3+5j), and Decimal and Fraction types (Chapter 14).
Floating point: why 0.1 + 0.2 ≠ 0.3
Computers store floats in binary (base 2). Many decimal fractions, like 0.1, cannot be written exactly in binary. It is the same as 1/3 in decimal: 0.3333… never ends. So Python stores the closest binary number it can.
Analogy: you measure a table with a ruler marked only in 1/8 inches. Most lengths come out a tiny bit off. The errors are small, but they can add up.
❌ Never compare floats with ==
✅ Compare with a tolerance
💡 Tip: for money, store whole cents as int (1999 instead of 19.99), or use decimal.Decimal (Chapter 14). This is the same advice as Java's BigDecimal, and it is not a Python bug. Every language that uses IEEE-754 floats behaves this way, JS and Java included.
Text (strings)
A string (str) is a sequence of characters. Use single quotes '…' or double quotes "…"; they mean the same thing. Pick whichever lets you avoid escaping.
The REPL shows a string's representation (with quotes). print() shows the text itself.
There is no separate char type: one character is just a string of length 1.
Raw strings and triple quotes
In a raw string (r"..."), backslashes are not special. That is useful for Windows paths and regular expressions (Chapter 13). Triple quotes ("""…""") let a string span several lines.
⚠️ Pitfall: an unknown escape like "\d" still works today, but Python prints SyntaxWarning: "\d" is an invalid escape sequence. A future version will make it an error. Use raw strings for regex patterns and Windows paths.
Joining and repeating
Joining adjacent literals is handy for breaking a long string across lines inside parentheses.
Indexing and slicing
Each character has an index (position) starting at 0. Negative indexes count from the end: -1 is the last character.
Think of the indexes as pointing between characters. The slice word[i:j] is everything between edge i and edge j. The start is included and the end is excluded.
An index that is too big is an error. A slice that is too big is quietly trimmed:
Strings are immutable
Immutable means "cannot be changed after it is created". You build a new string instead.
❌ Wrong
✅ Right
Everyday string methods
A method is a function attached to an object, called with a dot: text.upper(). Methods never change the original string; they return a new one.
☕ Java / 🟨 JS: str.join is "backwards" compared with JS: you call it on the separator, as in ", ".join(items), while JS writes items.join(", "). Compare strings with ==; there is no .equals().
Lists
A list holds an ordered sequence of items in square brackets. It is like a Java ArrayList or a JS array. Items can be of any type, though usually they are all the same type.
Unlike strings, lists are mutable: you can change them in place.
Lists can contain other lists (nesting):
Two names, one list (aliasing)
Assignment never copies. b = a makes b a second name for the same list. It is like two labels on one box. A slice, on the other hand, creates a new (shallow) copy.
☕ Java: this is exactly how object references behave in Java and JS. Python simply has no primitive types: every value, even 3, is an object, and every variable is a reference. Appendix A goes deeper.
First steps towards programming
Here is the classic Fibonacci series, where each number is the sum of the two before it. Read the comments line by line.
- Multiple assignment:
a, b = b, a + bevaluates the whole right side before assigning. So no temporary variable is needed to swap values:x, y = y, x. whileloops while a condition is true. Any non-zero number is true, and so is any non-empty string or list.0,""and[]are false.- Comparisons are
< > == <= >= !=. - Indentation is how Python groups statements. Use 4 spaces.
print() takes extra keyword arguments. end replaces the newline at the end, and sep replaces the space between items.
More examples
1. Splitting a bill
2. Cleaning up a messy expense note
3. File extension and name
4. Running totals in a list
5. Is it a palindrome?
Recap
/always gives a float.//floors,%follows the divisor's sign, and**is power (it binds tighter than unary minus).- Floats are binary approximations: compare with
math.isclose, and use integer cents orDecimalfor money. - Strings are immutable sequences: index from 0 or from the end with negatives; slices include the start and exclude the end.
- Lists are mutable. Assignment shares the list;
lst[:]copies it. a, b = b, a + bevaluates the right side first.whileloops on a condition.print(..., sep=, end=)controls output.
Exercises
Exercise 1 🟢 easy predict the output
Predict each result: 7 / 2, 7 // 2, 7 % 2, 2 ** 4.
Show solution
3.5, 3, 1, 16. Plain / always gives a float, even when the division is exact (8 / 4 is 2.0).
Exercise 2 🟢 easy predict the output
With s = "expense", what are s[0], s[-1], s[2:5], s[:3] and s[::2]?
Show solution
The slice [2:5] takes indexes 2, 3 and 4. The step 2 takes every other character, starting at index 0: e, p, n, e.
Exercise 3 🟢 easy fix the bug
The goal is to capitalise the first letter. Fix the code.
Show solution
Strings are immutable, so you build a new string and rebind the name to it.
Exercise 4 🟢 easy predict the output
What does this print?
Show solution
[1, 2, 3, 4] 4. b = a does not copy the list; both names point to the same list object.
Exercise 5 🟡 medium predict the output
Predict: -7 // 2, -7 % 2, -2 ** 2, int(-3.7).
Show solution
-4, 1, -4, -3. // rounds toward minus infinity, so % takes the divisor's sign. ** runs before unary minus. int() truncates toward zero, which is different from //.
Exercise 6 🟡 medium explain why
This loop adds 0.1 ten times. Why does it print False? How should you check it instead?
Show solution
0.1 has no exact binary form, and the tiny error in each addition adds up. Compare floats with a tolerance. The built-in sum() uses a more careful algorithm, so it hides the error in this case, but it can't help with == on floats in general.
Exercise 7 🟡 medium build it · playground
Create playground/initials.py that turns full_name = "ada lovelace byron" into A.L.B., using split, indexing and upper.
Show solution
parts[i][0] indexes twice: first the list, then the string. Chapter 3's for loop will make this shorter.
Exercise 8 🟡 medium refactor it
Rewrite this swap without the temporary variable.
Show solution
The right-hand side is evaluated completely before any name is reassigned.
Exercise 9 🔴 hard predict the output
What is the final value of letters?
Show solution
['_', 'a', 'X', 'd', 'e', 'Y', 'Z']. Assigning to a slice can change the list's length. The first step replaces two items with one. The second replaces the last item with two. [:0] is an empty slice at the start, so assigning to it inserts.
Exercise 10 🔴 hard mini-project · playground
Create playground/receipt.py. Given prices = [499, 1250, 99, 2000] (in cents), print each price as euros on its own line with print(..., sep=""), like €4.99. Then print the total and the average (in euros, rounded to 2 decimals). Use a while loop, // and %, and no floats until the average.
Show solution
Output: €4.99, €12.50, €0.99, €20.00, Total: €38.48, Average: €9.62. Whole cents keep every sum exact. The cents formatting is clumsy here; Chapter 9's f-strings shrink it to f"{p / 100:.2f}".