Краткий ответ: вы должны забыть о том, что полагаетесь на id
, чтобы попытаться глубже понять работу Python.На его вывод влияют детали реализации cpython, оптимизация глазка и повторное использование памяти.Чаще всего id
- это красная сельдь.Это особенно верно для numpy.
В вашем конкретном случае только a
и b
существуют как объекты python.Когда вы берете элемент a[0]
, вы создаете новый объект Python, скаляр типа numpy.float64
(или, возможно, numpy.float32
в зависимости от вашей системы).Это новые объекты Python, и поэтому им присваиваются новые id
, , если только интерпретатор не поймет, что вы пытаетесь использовать этот объект дважды (это, вероятно, происходит в вашем среднем примере, хотя я нахожуУдивительно, что двум numpy.float64
объектам с разными значениями присваивается один и тот же id
. Но странная магия исчезнет, если сначала назначить a[0]
и b[0]
собственным именам, так что это, вероятно, связано с некоторой оптимизацией).Может также случиться, что интерпретатор повторно использует адреса памяти, давая вам id
s, которые появились раньше.
Просто чтобы увидеть, как бесполезно id
с numpy, даже тривиальные представления - это новые объекты python сновые id
с, хотя для всех намерений и целей они так же хороши, как и оригинал:
>>> arr = np.arange(3)
>>> id(arr)
140649669302992
>>> id(arr[...])
140649669667056
А вот пример для id
повторного использования в интерактивной оболочке:
>>> id(np.arange(3))
140649669027120
>>> id(np.arange(3))
140649669028480
>>> id(np.arange(3))
140649669026480
Конечно, нет такой вещи, как int
интернирование для массивов numpy, так что вышеизложенное только из-за того, что интерпретатор повторно использует id
s.Тот факт, что id
возвращает адрес памяти, опять-таки просто деталь реализации cpython.Забудьте о id
.
Единственное, что вы можете использовать с numpy, это numpy.may_share_memory
и numpy.shares_memory
.