답변:
is
운영자가 테스트 하는 것을 오해했습니다 . 두 변수가 동일한 값을 갖는 것이 아니라 두 변수가 동일한 객체를 가리키는 지 테스트 합니다.
is
운영자를 위한 문서에서 :
개체 ID에 대한 연산자
is
및is not
테스트 : 과 동일한 개체 인x is y
경우에만 true 입니다.x
y
==
대신 연산자를 사용하십시오 .
print(x == y)
이것은 인쇄합니다 True
. x
그리고 y
두 가지 별도의 목록 :
x[0] = 4
print(y) # prints [1, 2, 3]
print(x == y) # prints False
당신이 사용하는 경우 id()
기능을 해당를 볼 수 있습니다 x
및 y
다른 식별자가 :
>>> id(x)
4401064560
>>> id(y)
4401098192
그러나 할당 y
하면 x
두 가지 모두 동일한 객체를 가리 킵니다.
>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True
와 is
쇼 모두 동일한 개체가,이 반환됩니다 True
.
Python에서 이름은 값을 참조하는 레이블 일뿐입니다 . 동일한 객체를 가리키는 여러 이름을 가질 수 있습니다. is
두 개의 이름이 하나의 동일한 객체를 가리키는 지 알려줍니다. ==
두 이름이 같은 값을 가진 객체를 참조하는지 알려줍니다.
A is B
는 id(A) == id(B)
.
id(A)
변수에 저장하지 않고 나중에 variable == id(B)
계속 작동 할 것으로 예상하는 경우 동일한 테스트에 대한 프록시입니다 . 경우 A
그 사이에 삭제 한 후 B
동일한 메모리 위치를 주어졌다 수 있습니다.
\n
>>> Y = 5 \n
>>> X는 Y이다 \n
트루 \n
>>> X == Y \n
트루 \n
>>>\n
또 다른 중복 은 두 개의 동일한 문자열이 일반적으로 동일하지 않은 이유를 묻는 것이 었는데, 여기에서는 실제로 대답하지 않았습니다.
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
그렇다면 왜 그들은 같은 문자열이 아닌가? 특히 다음과 같은 경우 :
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
두 번째 부분은 잠시 미루겠습니다. 첫 번째가 어떻게 사실 일 수 있습니까?
인터프리터는 문자열 값을 문자열 객체에 매핑하는 테이블 인 "인터 닝 테이블"을 가져야하므로 내용이있는 새 문자열을 만들 때마다 'abc'
동일한 객체를 반환합니다. Wikipedia 에는 인턴이 어떻게 작동하는지에 대한 자세한 논의가 있습니다.
그리고 파이썬 에는 문자열 인터 닝 테이블이 있습니다. sys.intern
메서드를 사용하여 수동으로 문자열을 인턴 할 수 있습니다 .
사실, 파이썬입니다 허용 자동으로 인턴 어떤 불변의 유형 있지만 필요 그렇게. 다른 구현은 다른 값을 인턴합니다.
CPython (사용중인 구현을 모르는 경우 사용하는 구현)은 작은 정수와 같은 일부 특수 싱글 톤을 자동 인턴 False
하지만 문자열 (또는 큰 정수, 작은 튜플 또는 기타)은 제외합니다. 이것은 매우 쉽게 볼 수 있습니다.
>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False
OK, 그러나 왜했다 z
과 w
동일?
그것은 인터프리터가 자동으로 인턴하는 것이 아니라 컴파일러 폴딩 값입니다.
동일한 컴파일 시간 문자열이 동일한 모듈에 두 번 나타나는 경우 (정확히 정의하기 어렵다는 의미입니다 r'abc'
. 'abc'
,, 'a' 'b' 'c'
은 (는) 모두 다른 리터럴이지만 동일한 문자열 이기 때문에 문자열 리터럴 과 동일하지 않지만 이해하기 쉽습니다.) 직관적으로) 컴파일러는 두 개의 참조가있는 문자열의 인스턴스를 하나만 만듭니다.
사실 컴파일러는 훨씬 더 나아갈 'ab' + 'c'
수 있습니다 'abc'
. 최적화 프로그램 에 의해 변환 될 수 있습니다 .이 경우 'abc'
동일한 모듈에서 상수 와 함께 접힐 수 있습니다 .
다시 말하지만 이것은 Python이 허용되지만 반드시 수행해야하는 것은 아닙니다. 그러나이 경우 CPython은 항상 작은 문자열 (예 : 작은 튜플)을 접습니다. (대화 형 인터프리터의 문별 컴파일러는 한 번에 모듈 단위 컴파일러와 동일한 최적화를 실행하지 않으므로 대화 형으로 정확히 동일한 결과를 볼 수 없습니다.)
그렇다면 프로그래머로서 이것에 대해 어떻게해야합니까?
글쎄… 아무것도. 두 개의 불변 값이 동일한 지 신경을 쓸 이유가 거의 없습니다. a is b
대신 사용할 수있는시기를 알고 싶다면 a == b
잘못된 질문을하는 것입니다. a == b
두 가지 경우를 제외하고 항상 사용하십시오 .
x is None
.x
이 y
.w
와 z
있기 때문에 값을 접는 컴파일러의 동일, 왜 REPL에서이 또한 작업은, 심지어 사용 않는 id()
참조를 확인하기 위해? Python 3.7에서 REPL 사용
a로 프롬프트 중복 된 질문 이 비유 작동 할 수 있습니다 :
# - Darling, I want some pudding!
# - There is some in the fridge.
pudding_to_eat = fridge_pudding
pudding_to_eat is fridge_pudding
# => True
# - Honey, what's with all the dirty dishes?
# - I wanted to eat pudding so I made some. Sorry about the mess, Darling.
# - But there was already some in the fridge.
pudding_to_eat = make_pudding(ingredients)
pudding_to_eat is fridge_pudding
# => False
is
그리고 is not
파이썬의 두 ID 연산자입니다. is
연산자는 변수의 값을 비교하지 않고 변수의 ID를 비교합니다. 이걸 고려하세요:
>>> a = [1,2,3]
>>> b = [1,2,3]
>>> hex(id(a))
'0x1079b1440'
>>> hex(id(b))
'0x107960878'
>>> a is b
False
>>> a == b
True
>>>
위의 예는 ID (Cpython의 메모리 주소 일 수도 있음)가 a
및 b
(값이 동일하더라도) 둘 다에 대해 다르다는 것을 보여줍니다 . 그렇기 a is b
때문에 두 피연산자의 ID가 일치하지 않아 false를 반환 한다고 말할 때 입니다. 그러나라고 말하면 연산은 두 피연산자에 동일한 값이 할당되어 있는지 확인 a == b
하기 때문에 true를 반환 ==
합니다.
흥미로운 예 (추가 등급) :
>>> del a
>>> del b
>>> a = 132
>>> b = 132
>>> hex(id(a))
'0x7faa2b609738'
>>> hex(id(b))
'0x7faa2b609738'
>>> a is b
True
>>> a == b
True
>>>
위의 예에서, 비록 a
및 b
두 개의 서로 다른 변수이다 a is b
리턴이 True
. 이 유형 때문이다 a
IS int
불변 오브젝트이다. 그래서 파이썬 (메모리를 절약하려고 생각합니다) b
은 동일한 값으로 생성되었을 때 동일한 객체를 할당했습니다 . 이 경우 그래서, 일치와 변수의 신원 a is b
밝혀졌다가되게합니다 True
.
이것은 모든 불변 객체에 적용됩니다 :
>>> del a
>>> del b
>>> a = "asd"
>>> b = "asd"
>>> hex(id(a))
'0x1079b05a8'
>>> hex(id(b))
'0x1079b05a8'
>>> a is b
True
>>> a == b
True
>>>
도움이 되었기를 바랍니다.
-5
보다 작 거나 높은 모든 것은 256
거짓입니다. Python은 [-5, 256] 범위의 숫자를 캐시합니다.
x is y
id(x) == id(y)
객체의 정체성을 비교하는 것과 같습니다 .
@ tomasz-kurgan이 아래 주석에서 지적했듯이 is
연산자는 특정 개체에서 비정상적으로 작동합니다.
예
>>> class A(object):
... def foo(self):
... pass
...
>>> a = A()
>>> a.foo is a.foo
False
>>> id(a.foo) == id(a.foo)
True
Ref;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24
여기에서 작은 정수로 확인할 수 있습니다. 257 이상의 숫자는 작은 정수가 아니므로 다른 객체로 계산됩니다.
==
이 경우 대신 사용 하는 것이 좋습니다 .
자세한 정보는 여기 : http://docs.python.org/2/c-api/int.html
X는 배열을 가리키고 Y는 다른 배열을 가리 킵니다. 이러한 배열은 동일하지만 is
연산자는 동일하지 않은 포인터를 살펴 봅니다.
is
운영자의 기능이이를 보여줍니다.
id
요청하지 않는 한조차 갖지 않습니다 .
과일을 사용한 간단한 예
fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist is newfruitlist )
print ( fruitlist is verynewfruitlist )
print ( newfruitlist is verynewfruitlist )
산출:
True
False
False
시도하면
fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist == newfruitlist )
print ( fruitlist == verynewfruitlist )
print ( newfruitlist == verynewfruitlist )
출력이 다릅니다.
True
True
True
== 연산자는 변수의 내용 만 비교하기 때문입니다. 두 변수의 ID를 비교하려면 is 연산자를 사용하십시오.
식별 번호를 인쇄하려면 :
print ( id( variable ) )