None, and finally the crucial idea of mutable versus immutable types.
- They decide which operators make sense —
"abc" * 3works (repeat), but"abc" − 1is an error. - They decide how Python stores the value in memory.
- The built-in function
type(x)tells you the type of any value.isinstance(x, int)tests it. - Whether a type is mutable (changeable after creation) or immutable affects how you use and share it.
9.1 The Built-in Data Type Tree
Python's standard data types fall into five broad categories. You have already met some of them in Chapter 8; this chapter studies each in detail.
9.2 Using type() to Inspect a Value
Python's built-in function type() returns the data type of any value or variable. Use it freely during learning and debugging — the interactive prompt is your friend.
print(type(42)) # <class 'int'> print(type(3.14)) # <class 'float'> print(type("hello")) # <class 'str'> print(type([1, 2, 3])) # <class 'list'> print(type(True)) # <class 'bool'> print(type(None)) # <class 'NoneType'>
9.3 Numeric Types — Numbers
Python has three numeric types for representing numbers.
9.3.1 Integer — int
Whole numbers without a decimal point. Unlike C/C++ or Java, Python integers have unlimited precision — the only ceiling is how much RAM you have.
age = 16 year = 2026 big = 10 ** 50 # 10⁵⁰ — perfectly fine neg = -273 crore = 1_00_00_000 # underscores allowed for readability
a = 0b1010 # binary → 10 in decimal b = 0o17 # octal → 15 in decimal c = 0x1F # hex → 31 in decimal print(a, b, c) # 10 15 31
9.3.2 Floating-point — float
Numbers with a decimal point or scientific notation. Internally stored as 64-bit IEEE-754 doubles, so you get about 15–17 significant digits of precision.
pi = 3.14159 temp = -40.0 tiny = 1.6e-19 # scientific notation → 1.6 × 10⁻¹⁹ avogadro = 6.022e23 # 6.022 × 10²³
print(0.1 + 0.2) # 0.30000000000000004When exact money arithmetic matters, use Python's
decimal module.
9.3.3 Complex — complex
Numbers of the form a + bj where a is the real part and b is the imaginary part. Python uses j (not i) as the imaginary unit — engineering convention. Rarely needed in CBSE programs, but examinable.
z1 = 2 + 3j z2 = complex(4, -5) # same as 4 - 5j print(z1.real, z1.imag) # 2.0 3.0 print(z1 + z2) # (6-2j)
9.3.4 Quick comparison
| Feature | int | float | complex |
|---|---|---|---|
| Example | 42 | 3.14 | 2 + 3j |
| Precision | Unlimited | ~15–17 digits | 2 × 15–17 digits |
| Fixed size? | No (grows as needed) | 8 bytes (IEEE-754) | 16 bytes |
| Typical use | counters, marks, indices | measurements, pi, π | signals, AC circuits |
9.4 Boolean — bool
The bool type has exactly two values: True and False (capital letters — case matters). It is technically a subclass of int, so in arithmetic True counts as 1 and False as 0.
pass_fail = True print(type(pass_fail)) # <class 'bool'> print(True + True) # 2 (True counts as 1) print(False * 10) # 0 # Boolean values result from comparisons: marks = 72 print(marks >= 33) # True print(marks == 100) # False
False: the number 0, the empty string "", empty list [], empty dict {}, and None. Everything else is True. That is why if name: is a common idiom meaning "if name is not empty".
9.5 Sequence Types
A sequence is an ordered collection of items. Every sequence shares a common set of operations: indexing with [i], slicing with [a:b], length with len(), membership test with in, concatenation with +, and repetition with *. Python has three built-in sequence types.
9.5.1 String — str
A sequence of Unicode characters enclosed in single, double, or triple quotes. Used for text. Strings are immutable.
name = "Aarav" msg = 'Hello, world!' para = """This is a multi-line string.""" print(name[0]) # A — indexing print(name[1:3]) # ar — slicing print(len(name)) # 5 print("a" in name) # True print(name + " K.") # Aarav K. print(name * 2) # AaravAarav
Strings are covered in full detail in Chapter 13.
9.5.2 List
An ordered, mutable sequence of items enclosed in square brackets [ ]. The items can be of different types and lists can even contain other lists. Think of a list as an Indian tiffin-box — ordered compartments that you can swap around or re-fill.
marks = [85, 72, 91, 68, 77] mixed = [1, "two", 3.0, True, [4, 5]] # different types, and nested list empty = [] print(marks[0]) # 85 marks[0] = 90 # ✓ mutable → element changed marks.append(100) # add at the end print(marks) # [90, 72, 91, 68, 77, 100]
Lists are covered in full detail in Chapter 14.
9.5.3 Tuple
An ordered, immutable sequence enclosed in round brackets ( ). Once created, you cannot change its items. Use tuples when the collection should stay fixed — e.g., the days of the week, a student's (roll_number, name) pair, GPS coordinates.
days = ("Mon", "Tue", "Wed", "Thu", "Fri") point = (12.97, 77.59) # lat/long of Bengaluru single = (7,) # 1-tuple — the trailing comma is required print(days[0]) # Mon print(len(days)) # 5 # days[0] = "Monday" # ❌ TypeError — tuples are immutable
Tuples are covered in full detail in Chapter 15.
9.5.4 String vs List vs Tuple — at a glance
| Property | String (str) | List | Tuple |
|---|---|---|---|
| Brackets | " " or ' ' | [ ] | ( ) |
| Ordered | Yes | Yes | Yes |
| Mutable | No | Yes | No |
| Element types | characters only | any, can mix | any, can mix |
| Typical use | text | a collection that may change | a fixed record of values |
9.6 Mapping — dict (Dictionary)
A dictionary stores a collection of key → value pairs enclosed in curly braces { }. You look up a value by its key (like looking up a word in a physical dictionary — English word → meaning). Keys must be unique and immutable (strings, numbers or tuples). Values can be anything.
student = {
"name": "Kavya",
"roll": 22,
"marks": [85, 72, 91],
"pass": True
}
print(student["name"]) # Kavya — look up by key
student["age"] = 16 # add a new key
student["roll"] = 23 # update an existing key
print(len(student)) # 5 (number of pairs)
print("roll" in student) # True
9.7 The None Type
None is Python's way of saying "no value" or "nothing here yet". It is the single value of the special type NoneType — comparable to null in Java or NULL in SQL.
result = None print(type(result)) # <class 'NoneType'> # A function that doesn't explicitly return a value returns None: def greet(name): print("Hi,", name) x = greet("Aarav") print(x) # None — there was no 'return'
is (identity) — not == — to test for None:
if result is None: # ✓ preferred ... if result == None: # works, but not idiomatic ...
9.8 Mutable vs. Immutable Data Types
9.8.1 Classification
| Category | Types | Why? |
|---|---|---|
| Immutable | int, float, complex, bool, str, tuple, None | Once created, the value cannot change. Any operation that looks like a change actually produces a new object. |
| Mutable | list, dict, set | You can add, remove, or replace items without creating a new object. |
9.8.2 Seeing it in action with id()
Python's built-in function id() returns the unique memory address of an object. Watching the ID change (or not) proves what is happening.
# ── str is immutable ── s = "hello" print(id(s)) # say, 140293846384240 s = s + " world" # looks like mutation, but… print(id(s)) # …a DIFFERENT id → a new object was built # ── list is mutable ── lst = [1, 2, 3] print(id(lst)) # e.g., 140293847123456 lst.append(4) print(id(lst)) # SAME id — the object was modified in place
9.8.3 Visualising the difference
9.8.4 Why does the distinction matter?
- Dictionary keys must be hashable — in practice, immutable. You can use a
str,intortupleas a key, but not alist. - Function arguments. When you pass a mutable object into a function, the function can change it visibly to the caller. With immutable objects this can never happen.
- Aliasing surprises. Two names can refer to the same mutable object — modifying one is visible through both.
a = [1, 2, 3] b = a # b is NOT a copy — it's another name for the same list b.append(99) print(a) # [1, 2, 3, 99] — surprised?
Useb = a.copy()orb = a[:]to get a real copy. - Thread safety. Immutable data is automatically safe to share between threads — no one can change it.
📌 Quick Revision — Chapter 9 at a Glance
- Data type decides what values a variable can hold and what operations are legal. Python infers it automatically.
- Five built-in categories: Number · Boolean · Sequence · Mapping · None.
- Numeric types:
int— whole numbers, unlimited precision, supports0b/0o/0xliterals.float— 64-bit IEEE-754, ~15-17 digits of precision, scientific notation withe.complex—a + bj(Python usesj, noti).
- Boolean — only
TrueandFalse; subclass ofintso arithmetic works. - Sequence types (ordered collections):
str— text in" "/' '/""" """. Immutable.list—[ ], mutable, mixed types allowed.tuple—( ), immutable, mixed types allowed. Use(7,)for a 1-tuple.
- Sequence common ops: indexing
[i], slicing[a:b],len(),in,+,*. - Mapping —
dict:{"key": value}, look up by key, mutable, order preserved since Python 3.7. - None — "no value". Single value of type
NoneType. Test withis None. - Mutable:
list, dict, set. Immutable:int, float, complex, bool, str, tuple, None. type(x)returns the type;id(x)returns the memory address. If an "edit" changesid, the type is immutable.- Immutable objects can be used as dictionary keys; mutable ones cannot.
- Assignment with a mutable object creates an alias (not a copy) — use
.copy()or slicing[:]for a real copy.