Python Data Types
Fundamentals Deep Dive
Python Data Types
Everything in Python is an object. Understand the built-in scalar, collection, and special-purpose types so you can model data accurately, reason about memory, and avoid mutation bugs.
4
Core categories
8+
Per-type satellites
5
Common pitfalls
Type categories
| Category | Types | Notes |
|---|---|---|
| Scalars | int, float, complex, bool, NoneType | Immutable, safe to share across code paths |
| Text & binary | str, bytes, bytearray | Strings are Unicode; bytes for binary payloads |
| Collections | list, tuple, set, frozenset, dict | Some mutable, some immutable |
| Special | range, memoryview, custom classes | Often behave like iterables/sequences |
All built-in types inherit from object, and you can interrogate them via type() or isinstance().
Mutability matrix
| Type | Mutable? | Typical use case |
|---|---|---|
| int / float / bool / str / tuple | ❌ Immutable | Safe as dict keys or set members |
| list / dict / set / bytearray | ✅ Mutable | Modify collections in place |
| frozenset | ❌ Immutable | Use inside other sets or as keys |
| dataclass(frozen=True) | ❌ Immutable | Model read-only configuration |
Mutability determines whether two references can interfere with each other. For example:
items = [1, 2, 3]
alias = items
alias.append(4)
print(items) # [1, 2, 3, 4]
Copy mutable objects (items.copy() or copy.deepcopy) when isolation matters.
NoneType
None signals "no value" and is falsy. Check explicitly with is None and avoid storing sentinel integers or strings to represent emptiness.
Type casting
| Call | Result |
|---|---|
| str(number) | Convert to string |
| int(string) | Parse integer; ValueError if invalid |
| list(iterable) | Break iterable into list of elements |
| tuple(iterable) | Create immutable snapshot |
| set(iterable) | Remove duplicates + enable set math |
Always validate user input before casting. Pair conversion with exception handling when parsing external data.
Nested and composite types
Combine built-ins to represent complex shapes:
from typing import TypedDict, List
class Course(TypedDict):
id: str
tags: List[str]
meta: dict[str, str]
courses: list[Course] = [...]
Python 3.9+ supports list[str] and dict[str, int] generics without importing typing.
Performance considerations
- Tuples are slightly faster than lists for fixed data because they're immutable and hashable.
- Sets and dicts provide O(1) average-time membership checks thanks to hashing.
- Lists are efficient for sequential data but expensive for insertions/deletions in the middle.
Next up in your learning path
Frequently Asked Questions
Are lists passed by reference or value?
Python passes references to objects. When you pass a list to a function, both caller and callee refer to the same list unless you explicitly copy it.
Why do I sometimes see "Truthy" and "Falsy"?
Python evaluates non-Boolean objects in Boolean contexts. For example, empty containers, `0`, and `None` are falsy; most other values are truthy. This enables idioms like `if not items:`.
When should I use Decimal instead of float?
Use `decimal.Decimal` for currency or precision-critical applications. Floats use binary fractions and can't represent some decimal numbers exactly, leading to rounding errors.