2016-10-21 3 views
3

Я полный новичок для Python, поэтому, пожалуйста, вы могли бы объяснить мне, почему происходит следующая ситуация. Рассмотрим следующий код:Python slice показывает то же местоположение id

>>> A = [1, 2, 3, 4] 
>>> B = A[0:2] 
>>> print id(A) == id(B) 
False 
>>> print id(A[0]) == id(B[0]) 
True        #Why? 
>>> A[0] = 9 
>>> A 
[9, 2, 3, 4] 
>>> B 
[1, 2] 
>>> print id(A[0]) == id(B[0]) 
False        #Contradiction? 

Как вы можете видеть из приведенного выше кода, я Нарезать список А и скопировать его в B, но, почему print id(A[0]) == id(B[0]) расценивается True на первый, но наоборот, когда я изменить либо от значения A или B?

+1

[CPython кэширует небольшие целые числа] (http://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers), поэтому любое значение от -5 до 256 будет иметь тот же идентификатор в любое время вы Проверь это. –

+0

http://stackoverflow.com/questions/28329498/why-does-a-space-affect-the-identity-comparison-of-equal-strings/28329522#28329522 –

ответ

2

Когда вы делаете B = A[0:2], это в основном делает это, как часть его: B[0] = A[0]. Таким образом, объект (целое число 1) в A[0] - это тот же объект, который находится в B[0].

Когда вы установили A[0] = 9, тогда эти объекты недолго останутся прежними.

Также, как @ ŁukaszRogalski указал, что CPython кэширует маленькие целые числа. Итак, у нас есть A[0] == 1 == B[0] и id(1) == id(1).

Когда A[0] == 9, затем 9 != 1 == B[0] и id(9) != id(1).

+0

oh, поэтому он не имеет ничего общего с местоположением памяти ? –

+0

https://docs.python.org/2/library/functions.html#id Если это CPython, это будет память. Но если это не так, просто гарантируется уникальность уникального объекта. –

+0

Кроме того, мой ответ немного выключен. Подождите, пока я его отрегулирую. –

2

Попробуйте это:

id(1) == id(1) #True 

Причина заключается в том, что эти цифровые константы будут повторно использованы в течение всей программы. Так что, как и некоторая память, для хранения 1, а затем, где указано 1 в программе, будет использоваться одна и та же память, поэтому будет создана только ссылка на эту память. Объект остается тем же.

+0

О, я изначально думал, что он всегда выбирает местоположение памяти, а чем фактическое значение. :) –

+0

Будьте уверены, что в вашем случае A и B относятся к разным вещам. – Shasha99

+0

@Burak это делает, но python будет хранить только один объект для каждого целого числа. – Aaron

1

В принципе, python не создает новые объекты из каждого элемента в списке, всякий раз, когда вы копируете/нарезаете его.

Но, хотя это не вызовет каких-либо проблем с неизменяемыми объектами, вы должны быть осторожны с изменяемыми объектами:

In [22]: A = [[1, 2], 2, 3, 4] 

In [23]: B = A[0:2] 

In [24]: id(A[0]) == id(B[0]) 
Out[24]: True 

In [27]: A[0][1] = 99 

In [28]: B 
Out[28]: [[1, 99], 2] 

В этом случае вы можете использовать copy.deepcopy, чтобы создать новый объект срезе:

In [32]: import copy 

In [33]: B = copy.deepcopy(A[0:2]) 

In [34]: A[0][1] = 5 

In [35]: B 
Out[35]: [[1, 99], 2] 

In [36]: id(A[0]) == id(B[0]) 
Out[36]: False 
     ^
     New Object 
Смежные вопросы