import numpy as np
array_1 = np.array([1,2,3])
array_2 = np.array([4,5,6])
print(id(array_1))
print(id(array_2))
print(f"array id comparison = {id(array_1)==id(array_2)}")
print(id(array_1[0]))
print(id(array_2[0]))
print(f"array item id comparison = {id(array_1[0])==id(array_2[0])}")
Output:
553196994064
553197145904
array id comparison = False
553211404432
553211405200
array item id comparison = True*
The ids of array items are different, but why is the comparison of ids of array items True?
CodePudding user response:
A new object (of type numpy.int32
) is created each time you access the array elements directly:
>>> id(array_1[0])
3045147529104
>>> id(array_1[0])
3045147529008
>>> id(array_1[0])
3045147527984
When you issue
id(array_1[0]) == id(array_2[0])
after getting the first id, the first object is deleted because there are no references pointing to it, making it unreachable. The second object is then created at the same memory address (and therefore with the same id). Both of this happens before the equality operator comes into play.
When you assign a name to the first object you can prevent its deletion, because now it has a reference pointing to it.
>>> id(array_1[0]) == id(array_2[0])
True
>>> id(x := array_1[0]) == id(array_2[0])
False
CodePudding user response:
array_1[0]
and array_2[0]
both create new objects; they do not simply return references to existing Python objects. As such, the object returned by array_1[0]
can be garbage collected as soon as id(array_1[0])
returns, which means the ID previously allocated to that object is free to be reused by the object returned by array_2[0]
.