What is a variable in Python?
In many languages, a variable is a named box in memory.
You declare int x = 5 and a piece of RAM labeled "x" holds the number 5.
Change x, and the bytes inside that box change.
Python is different. Python variables are names — labels that point to objects.
When you write x = 42, Python:
- Creates an integer object
42somewhere in memory (the heap) - Binds the name
xin the current namespace to that object
The variable x doesn't "contain" 42.
It references the object that contains 42.
This distinction matters more than you'd think.
What is id()?
Every object in Python has a unique identity: its memory address (or a proxy for it).
The built-in function id(x) returns this address as an integer.
Two variables with the same id() point to the exact same object —
no copy was made.
is vs ==== checks value equality — do the objects look the same?is checks identity — are they literally the same object in memory?Use
is None, is True, is False for singletons.
For everything else, prefer ==.
How Python tracks when to free memory
Every heap object carries a hidden counter: its reference count. It records how many names (or containers) currently point to the object. CPython adjusts this counter automatically as variables are bound and unbound.
Refcount increases when a new name is bound to the object
(x = obj, b = a, or passing it as a function argument).
Refcount decreases when a name is rebound (x = other),
deleted (del x), or goes out of scope (function returns).
When refcount reaches 0, CPython immediately frees the object's memory. No waiting, no delay — garbage collected on the spot.
The most important distinction in Python
Understanding the difference between mutation and rebinding is the single most useful mental model for reasoning about Python code.
Immutable types (int, str, float, tuple) can
only be rebounded — you can never change the object itself.
Mutable types (list, dict, set) can be both mutated
and rebound.
| Operation | Example | Creates new object? | id() changes? | Other aliases see change? |
|---|---|---|---|---|
| Rebind | x = 99 |
✅ Yes | ✅ Yes | ❌ No |
| Augmented rebind | x += 1 (int) |
✅ Yes | ✅ Yes | ❌ No |
| Mutate (append) | lst.append(x) |
❌ No | ❌ No | ✅ Yes |
| Mutate (index) | lst[0] = x |
❌ No | ❌ No | ✅ Yes |
| Augmented rebind | lst += [x] (list) |
❌ No* | ❌ No* | ✅ Yes* |
* For lists, += calls __iadd__ which mutates in-place (unlike with immutable types).
All the Variable Types
Python has many built-in types. The most important thing to know about each is: is it mutable or immutable?
x = -7
x = 0
x += 1 creates a new int object, doesn't change the old one.x = 2.0
x = -0.5
s = 'world'
s = """multi
line"""
s[0] = 'H' raises a TypeError.active = False
int! True == 1, False == 0. Immutable singleton objects.t = ("a", True)
nums.append(4)
nums[0] = 99
d["b"] = 2
del d["a"]
s.add(4)
s.discard(1)
Quick Reference: Mutability at a glance
| Type | Literal | Mutable? | Why it matters |
|---|---|---|---|
| int | 42 |
❌ No | x += 1 rebinds x to a new object |
| float | 3.14 |
❌ No | Any arithmetic produces a new float |
| str | "hello" |
❌ No | String methods return new strings; you can't change characters in-place |
| bool | True |
❌ No | Only two boolean objects exist; they're singletons |
| NoneType | None |
❌ No | One None object exists; always use is None to check |
| tuple | (1, 2) |
❌ No | Can't add/remove/change; safe to use as dict keys |
| list | [1, 2] |
✅ Yes | Functions can modify the list you passed — be careful with aliases! |
| dict | {"k": v} |
✅ Yes | Passed by reference; mutations inside functions persist |
| set | {1, 2} |
✅ Yes | Can grow/shrink; elements must be immutable/hashable |
a = [1, 2, 3] then b = a does NOT copy the list.
Both a and b point to the same list object.
Doing b.append(4) will also affect a!
Use b = a.copy() or b = list(a) to get an independent copy.
id(5) == id(5) is always True,
and two variables both set to 5 will share the exact same object.
For large integers, each assignment creates a new object.
This is an optimization detail, not a language guarantee.