id()
The identity of an object as an integer. `x is y` is faster and safer than `id(x) == id(y)`.
Common call
id(x)
Returns
an int — implementation-specific (memory address in CPython)
Replaces
the `is` operator when you need an integer form of the identity
Watch out
small ints and interned strings share ids; ids are RECYCLED after garbage collection
id(objectobject — Any object. id() returns an integer identifier that stays constant for the object's lifetime.type: Any · required)
→ int
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| object | Any | yes | Any object. id() returns an integer identifier that stays constant for the object's lifetime. |
Return value
int — An integer guaranteed to be unique and constant for the object during its lifetime. In CPython this is the memory address; other implementations may use different schemes. Two non-overlapping objects can share an id if the first was garbage-collected before the second was created.
Common patterns
Check for object identity
Prefer `is` over id() comparisons — same meaning, cleaner code.
if x is y: ... # NOT: if id(x) == id(y): ...
Detect aliasing during debugging
When two names point to the same object, id() confirms it.
a = [1, 2] b = a print(id(a), id(b)) # same
Sentinel object pattern
A unique `object()` gives you a sentinel whose id is unique.
_MISSING = object() if d.get(key, _MISSING) is _MISSING: ...
Examples
1. Same object same id
x = [1]
y = x
id(x) == id(y)
Returns
True2. Different objects
id([1]) == id([1])
Returns
False # two lists3. Small int caching
a = 5
b = 5
id(a) == id(b)
Returns
True # CPython caches small ints4. Large int not cached
a = 10**10
b = 10**10
id(a) == id(b)
Returns
False (or True depending on interpreter)5. None is a singleton
id(None) == id(None)
Returns
True6. Prefer `is`
x is None # canonical
Returns
idiomaticPitfalls
1. IDs are RECYCLED after garbage collection
When an object is destroyed, its id may be reused by a new object. `id(x) == id(y)` is unreliable across the lifetimes of the objects — only within.
Recycled
a = "temp" old_id = id(a) del a b = create_new() id(b) == old_id
may accidentally be True
Compare live
if a is b: # only meaningful when both exist
safe
2. Small ints and interned strings share ids
CPython caches small integers (-5 to 256) and common strings. `id(a) == id(b)` for two small ints of the same value returns True — an optimization detail, not something to rely on.
Implementation detail
a, b = 5, 5 id(a) == id(b)
True # CPython small-int cache
Use == for value equality
a == b
True — always for equal values
3. Prefer `is` over id() comparisons
Every use of `id(x) == id(y)` should be `x is y`. Same result, cleaner code, harder to accidentally compare with something that has a matching id-like integer.
Verbose
if id(x) == id(y):
unclear intent
Idiomatic
if x is y:
clean
4. The int returned is IMPLEMENTATION-SPECIFIC
CPython returns the memory address. PyPy uses a different scheme. Do NOT persist ids across runs — they mean nothing outside the current process.
Persisted
save_to_disk(id(x))
meaningless later
Use a real key
save_to_disk(x.uuid or x.id)
stable across runs
When to use
Use it
- Sentinel object() pattern for "distinct from all values"
- Debugging aliasing (rare, but useful when it happens)
- Weak-reference bookkeeping in advanced code
- Rarely: as a hashable identity when the object cannot define __hash__
Reach for something else
- Identity check → `is` is cleaner
- Persisting an identifier → use a UUID or database ID
- Cross-process communication → id is meaningless outside the process
- Anything security-related — never rely on id for uniqueness against an attacker
Notes
Complexity
O(1)
Return
An integer — the memory address in CPython
CPython impl
Python/bltinmodule.c :: builtin_id — returns PyLong_FromVoidPtr(obj)
Memory
No allocation beyond the returned int
Thread-safe
Yes
FAQ
id gives object IDENTITY — two lists with the same elements have DIFFERENT ids. hash gives value HASH — two lists with the same elements would give the same hash if lists were hashable. Different questions, different answers.
History
1.0
id() has been a builtin since Python 1.0.
3.0
Return type is int (was a long in Python 2 on 64-bit systems).