Первый тест со списком:
In [1109]: a=[0,1,2,3,4]
In [1112]: b=a[1:3]
In [1113]: id(a[1])
Out[1113]: 139407616
In [1114]: id(b[0])
Out[1114]: 139407616
In [1115]: a[1] is b[0]
Out[1115]: True
позже я попытался
In [1129]: id(1)
Out[1129]: 139407616
Так объект в a[1]
последовательно целое 1
(id
целых чисел является немного сложнее, и зависит от реализации).
Но с массивом:
In [1118]: aa=np.arange(5)
In [1119]: ba=aa[1:]
In [1121]: aa[1]
Out[1121]: 1
In [1122]: ba[0]
Out[1122]: 1
In [1123]: id(aa[1])
Out[1123]: 2925837264
In [1124]: id(ba[0])
Out[1124]: 2925836912
id
совершенно различны; на самом деле они изменяются при каждом доступе:
In [1125]: id(aa[1])
Out[1125]: 2925837136
In [1126]: id(ba[0])
Out[1126]: 2925835104
Это потому, что aa[1]
не только целое число 1
. Это объект np.int32
.
In [1127]: type(aa[1])
Out[1127]: numpy.int32
В отличие от списка, значения массива хранятся в виде байтов в databuffer
. b[1:]
- это view
и обращается к тому же буферу данных. Но a[1]
- это новый объект, содержащий ссылку на этот буфер данных. В отличие от списка, a[1]
не является вторым объектом в a
.
В общем, id
не полезен при работе с массивами, а тест is
также не пригоден. Используйте ==
или isclose
(для поплавков).
================
Путь, чтобы увидеть, где значения aa
сохраняются в с:
In [1137]: aa.__array_interface__
Out[1137]:
{'data': (179274256, False), # 'id' so to speak of the databuffer
'descr': [('', '<i4')],
'shape': (5,),
'strides': None,
'typestr': '<i4',
'version': 3}
In [1138]: ba.__array_interface__
Out[1138]:
{'data': (179274260, False), # this is 4 bytes larger
'descr': [('', '<i4')],
'shape': (4,),
'strides': None,
'typestr': '<i4',
'version': 3}
data
указатель для 2 связаны с тем, что ba
является view
.
aa[1]
является массивным, а также имеет буфер данных, но это не представление.
In [1139]: aa[1].__array_interface__
Out[1139]:
{'__ref': array(1),
'data': (182178952, False),
...}
Это может работать со списками, которые содержат указатели на объекты. Но массив хранит значения в буфере данных. 'a [2]' - это новый объект со ссылкой на этот буфер, но его 'id' не имеет ничего общего с' a' или databuffer. Поэтому 'id' не пригодится при работе с массивами. – hpaulj
Полу-дубликат http://stackoverflow.com/questions/3877230/why-does-id-id-and-id-id-in-cpython. Хотелось бы, чтобы у нас была функция «split duplicate». – user2357112