Built-in types and the mutable/immutable split
I group the built-ins by role: numeric (int, float, complex, bool), text and binary (str, bytes, bytearray, memoryview), sequences (list, tuple, range), mappings (dict), sets (set, frozenset), and the singleton NoneType. The categorization that matters in practice is mutability: can the object's own state change in place after creation? That is a property of the object, not of the variable name. Rebinding a name never mutates anything.
Immutable: int, float, complex, bool, str, bytes, tuple, frozenset, range, NoneType
Mutable: list, dict, set, bytearray (plus most user-defined class instances by default)
Mutability drives hashability: only hashable objects can be dict keys or set members, and built-in mutable containers are deliberately unhashable
bool is a subclass of int, so True + True == 2 and isinstance(True, int) is True
The 'why' behind the split: immutable objects can be safely shared, cached, interned and used as dictionary keys because their hash can never change. Mutable objects give you cheap in-place updates (list.append is amortized O(1)) at the cost of aliasing bugs. The trade-off shows up in everyday choices: tuple vs list for fixed records, frozenset vs set for constant lookup tables or dict keys, and str concatenation in a loop (creates new objects each time) vs ''.join or io.StringIO.
Common misconceptions: (1) 'a tuple is fully immutable' - it only guarantees its references never change, so a tuple holding a list is mutable in effect and not hashable; (2) 'x += 1 mutates the int' - it rebinds x to a new int; (3) mutable default arguments, which is the classic production bug from this topic. The fix is a None default and creating the list inside the function. Note that += on a list does mutate in place (via iadd), which is why a += b and a = a + b behave differently for lists.
Version notes: dict preserves insertion order as a language guarantee from 3.7 (an implementation detail in CPython 3.6). Dict/set views and the 3.9+ dict union operators do not change mutability rules. Type hints (list[int], etc.) are not enforced at runtime.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience