id()

The identity of an object as an integer. `x is y` is faster and safer than `id(x) == id(y)`.

Built-in functionPython 1.0+
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(objectobjectAny object. id() returns an integer identifier that stays constant for the object's lifetime.type: Any · required)
int

Parameters

NameTypeRequiredDescription
objectAnyyesAny object. id() returns an integer identifier that stays constant for the object's lifetime.

Return value

intAn 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
True
2. Different objects
id([1]) == id([1])
Returns
False # two lists
3. Small int caching
a = 5 b = 5 id(a) == id(b)
Returns
True # CPython caches small ints
4. 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
True
6. Prefer `is`
x is None # canonical
Returns
idiomatic

Pitfalls

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).