Массив dtype object
хранит указатели на содержащиеся в нем объекты. В CPython это соответствует id
. Каждый раз, когда вы создаете новый список, он будет размещен по новому адресу памяти. Однако небольшие целые числа интернированы, поэтому 1
будет ссылаться на один и тот же целочисленный объект каждый раз.
Вы можете точно увидеть, как это работает, проверив идентификаторы некоторых примеров объектов:
>>> x = np.array([1, [2]])
>>> x.tobytes()
b'\x90\x91\x04a\xfb\x7f\x00\x00\xc8[J\xaa+\x02\x00\x00'
>>> id(x[0])
140717641208208
>>> id(1) # Small integers are interned
140717641208208
>>> id(x[0]).to_bytes(8, 'little') # Checks out as the first 8 bytes
b'\x90\x91\x04a\xfb\x7f\x00\x00'
>>> id(x[1]).to_bytes(8, 'little') # Checks out as the last 8 bytes
b'\xc8[J\xaa+\x02\x00\x00'
Как видите, это вполне детерминировано c, но сериализует информацию, которая по сути бесполезна для вас. Операция для массивов цифр c такая же, как и для массивов объектов: она возвращает представление или копию базового буфера. Содержимое буфера - это то, что сбивает вас с толку.
Поскольку вы упомянули, что вы вычисляете хэши, имейте в виду, что существует причина, по которой списки python не подлежат хешу. Вы можете иметь списки, которые равны в одно время и разные в другое. Использование идентификаторов, как правило, не очень хорошая идея для эффективного га sh.