How to Compare Memory Addresses of Objects in Python
In Python, every object is stored at a specific location in memory. While we typically compare objects based on their value (e.g., is 5 == 5?), there are scenarios, such as debugging shared references or optimizing performance, where you need to compare their identity (memory address).
This guide explores how to access memory addresses using the id() function and how to compare object identities using the is operator.
Understanding Object Identity and id()
Every object in Python has a unique identifier that remains constant during its lifetime. In the CPython implementation (the standard Python), this identifier is the actual memory address of the object.
To view this address, Python provides the built-in id() function.
my_object = "Hello, Tutorial Reference!"
# ✅ Correct: Accessing the memory address (integer representation)
address = id(my_object)
print(f"Object Value: {my_object}")
print(f"Memory Address: {address}")
print(f"Hex Address: {hex(address)}")
Output:
Object Value: Hello, Tutorial Reference!
Memory Address: 140101198300304
Hex Address: 0x7f6bda284490
Method 1: Using the is Operator (Recommended)
The most Pythonic and efficient way to compare memory addresses is using the is operator.
==checks if values are equal.ischecks if identities (memory addresses) are the same.
Comparing Mutable Objects (Lists)
Even if two lists contain the exact same data, they are distinct objects in memory.
list_a = [1, 2, 3]
list_b = [1, 2, 3]
list_c = list_a # Comparison by assignment (Aliasing)
# ⛔️ Confusion: Values are equal, but are they the same object?
print(f"Values are equal? {list_a == list_b}")
# ✅ Correct: Comparing memory addresses
print(f"Is list_a the same object as list_b? {list_a is list_b}")
print(f"Is list_a the same object as list_c? {list_a is list_c}")
Output:
Values are equal? True
Is list_a the same object as list_b? False
Is list_a the same object as list_c? True
The is operator is faster than comparing id(a) == id(b) because it does not require the overhead of calling a function and creating integer objects for the return values.
Method 2: Comparing id() Values Directly
You can manually extract the IDs and compare the integers. This is functionally equivalent to is, though less readable. This method is useful if you need to log the specific addresses for debugging purposes.
obj1 = "Python"
obj2 = "Python"
obj3 = "Java"
# Python often optimizes small strings/integers to point to the same memory (Interning)
# ✅ Correct: Comparing specific memory IDs
if id(obj1) == id(obj2):
print(f"obj1 and obj2 share address: {id(obj1)}")
else:
print("obj1 and obj2 are different objects.")
if id(obj1) == id(obj3):
print("Same object.")
else:
print(f"Different objects. {id(obj1)} vs {id(obj3)}")
Output:
obj1 and obj2 share address: 140247016483184
Different objects. 140247016483184 vs 140247016527536
Be cautious with small integers and short strings. Python caches (interns) them to save memory. a = 1 and b = 1 will usually have the same ID, but a = 1000 and b = 1000 might not, depending on the implementation.
Practical Use Case: Detecting Shared References
A common bug in Python arises from aliasing, where two variables point to the same mutable object. Modifying one variable inadvertently modifies the other. Comparing addresses helps detect this.
def modify_data(source_list):
# ⛔️ Incorrect: Modifying the list directly affects the original variable
# source_list.append(4)
# ✅ Correct: Check identity to prevent side effects or confirm intention
new_list = source_list # Aliasing
print(f"DEBUG: Source ID: {id(source_list)}")
print(f"DEBUG: New List ID: {id(new_list)}")
if source_list is new_list:
print("Warning: Variables point to the same memory address.")
data = [1, 2, 3]
modify_data(data)
Output:
DEBUG: Source ID: 140476179966208
DEBUG: New List ID: 140476179966208
Warning: Variables point to the same memory address.
Conclusion
To compare objects in Python:
- Use
isfor checking if two variables refer to the exact same object in memory. - Use
id()if you need to visualize or log the specific memory address for debugging. - Remember that
a is bimpliesa == b(same object implies same value), buta == bdoes not implya is b.