How to Check Memory Addresses in Python
In Python, everything is an object stored in memory. While Python handles memory management automatically (unlike C or C++), there are times when you need to inspect memory addresses for debugging, optimizing performance, or verifying if two variables point to the same object.
This guide explains how to retrieve memory addresses using the built-in id() function, convert them to hexadecimal format, and check for object identity.
Understanding Memory Addresses
A memory address is a unique identifier (an integer) representing the specific location in your computer's RAM where an object is stored. In the standard CPython implementation, the address returned by Python corresponds to the actual memory address of the object structure.
- Uniqueness: No two objects with overlapping lifetimes can have the same ID.
- Constancy: An object's ID never changes once created.
Method 1: Using the id() Function (Standard)
The most direct way to get a memory address is the built-in id() function. It returns the address as a base-10 integer.
x = 42
address = id(x)
print(f"Value: {x}")
print(f"Memory Address (Decimal): {address}")
Output (will vary every run):
Value: 42
Memory Address (Decimal): 140541345023504
Method 2: Converting to Hexadecimal
Memory addresses are conventionally represented in hexadecimal (base-16) format in low-level programming and debugging tools. You can convert the integer returned by id() using the hex() function.
data = [1, 2, 3]
# Get the ID and convert to hex
dec_addr = id(data)
hex_addr = hex(dec_addr)
print(f"List: {data}")
print(f"Decimal Address: {dec_addr}")
print(f"Hex Address: {hex_addr}")
Output:
List: [1, 2, 3]
Decimal Address: 140425209473280
Hex Address: 0x7fb74aba6900
When you print a standard object in Python (one without a custom __repr__), the default output usually includes the hex memory address.
class MyObj:
pass
obj = MyObj()
print(obj)
Output:
<__main__.MyObj object at 0x000001FC5B2E3A40>
Method 3: Checking Object Identity (is operator)
While id() gives you the number, you rarely need to compare the numbers manually. To check if two variables point to the same memory address, use the is operator.
a is breturnsTrueifid(a) == id(b).a == breturnsTrueif the contents are equal.
list_a = [10, 20]
list_b = list_a # list_b references the SAME object as list_a
list_c = [10, 20] # list_c is a NEW object with the same content
print(f"A address: {hex(id(list_a))}")
print(f"B address: {hex(id(list_b))}")
print(f"C address: {hex(id(list_c))}")
print(f"A is B? {list_a is list_b}") # True (Same address)
print(f"A is C? {list_a is list_c}") # False (Different address)
print(f"A == C? {list_a == list_c}") # True (Same content)
Output:
A address: 0x7fef8b666900
B address: 0x7fef8b666900
C address: 0x7fef8b679400
A is B? True
A is C? False
A == C? True
Common Pitfall: Small Integer Caching
Python performs memory optimization for small integers (typically between -5 and 256). These objects are pre-allocated and cached. This means two separate assignments of 100 will point to the same memory address, whereas two assignments of 1000 might not (depending on how the code is executed).
# Small integers are cached (Interning)
a = 100
b = 100
print(f"100 is 100? {a is b}") # True
# Larger integers might not be cached immediately in interactive mode
x = 257
y = 257
print(f"257 is 257? {x is y}")
# Often False in console, but might be True in scripts due to compiler optimization
Output:
100 is 100? True
257 is 257? True
Do not rely on id() or is for comparing integers or strings unless you specifically intend to check memory identity. Always use == for value comparison.
Conclusion
To check memory addresses in Python:
- Use
id(obj)to get the unique integer identifier (memory address). - Use
hex(id(obj))to view the address in the standard hexadecimal format. - Use
a is bto check if two variables refer to the exact same object in memory.