2016-10-22 6 views
1

Что здесь происходит? Похоже, что расположение id массива не остается устойчивым, может быть, оператор возвращается False, даже думал, что идентификаторы одинаковы. то после печати массивов изменяются элементы элементов. Любые объяснения?Изменение размера массива памяти ID

import numpy as np 
a = np.arange(27) 
b = a[1:5] 
a[0] is b[1] #False 
id(a[0]) #40038736L 
id(b[1]) #40038736L 
a #prints the array 
id(b[1]) #40038712L 
id(a[0]) #40038712L 
b[0] #1 
a[1] #1 
id(b[0]) #40038712L 
id(a[1]) #40038784L 
+2

Это может работать со списками, которые содержат указатели на объекты. Но массив хранит значения в буфере данных. 'a [2]' - это новый объект со ссылкой на этот буфер, но его 'id' не имеет ничего общего с' a' или databuffer. Поэтому 'id' не пригодится при работе с массивами. – hpaulj

+0

Полу-дубликат http://stackoverflow.com/questions/3877230/why-does-id-id-and-id-id-in-cpython. Хотелось бы, чтобы у нас была функция «split duplicate». – user2357112

ответ

1

Первый тест со списком:

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), 
...} 
+0

Не могли бы вы немного рассказать о том, почему идентификаторы меняются с каждым доступом для aa [1]. Получается ли сбор мусора и создается заново каждый раз, когда на нем вызывается идентификатор? –

+0

Это не вопрос сбора мусора. 'aa [1]' создается вызовом метода 'aa .__ getitem __ ((1))'. Каждый раз создается новый объект 'np.int32'. – hpaulj

Смежные вопросы