not - string same python




파이썬에서 '=='또는 'is'를 사용하여 문자열을 비교하는 것이 때로는 다른 결과를 산출하는 이유는 무엇입니까? (10)

Python에 대한 나의 제한된 경험에서, is 는 두 객체를 비교하여 같은 값을 가진 두 개의 다른 객체가 아닌 동일한 객체인지 확인하는 데 사용됩니다. == 는 값이 동일한 지 결정하는 데 사용됩니다.

다음은 좋은 예입니다.

>>> s1 = u'public'
>>> s2 = 'public'
>>> s1 is s2
False
>>> s1 == s2
True

s1 은 유니 코드 문자열이고 s2 는 일반 문자열입니다. 그들은 같은 유형이 아니지만 같은 가치입니다.

두 변수가 'public' 값으로 설정된 Python 프로그램이 있습니다. 조건식에서 나는 var1 is var2 인 비교를했지만 var1 == var2 변경하면 True 반환합니다.

이제 파이썬 인터프리터를 열고 같은 "비교"를하면 성공합니다.

>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True

내가 여기서 무엇을 놓치고 있니?


그 밖의 해답은 정확합니다 : is동일성 비교에 사용되는 반면, is신원 비교에 사용됩니다. 당신이 신경 쓰는 것은 평등 (두 개의 문자열은 같은 문자를 포함해야합니다)이므로,이 경우에는 is 연산자가 잘못되어 간단히 == 를 사용해야합니다.

그 이유 is (대부분의) 문자열 리터럴이 기본적으로 interned 되기 때문입니다. 위키 백과에서 :

인턴 된 문자열은 문자열 비교를 가속화합니다. 이는 문자열 키가있는 해시 테이블에 크게 의존하는 응용 프로그램 (예 : 컴파일러 및 동적 프로그래밍 언어 런타임)의 성능 병목 현상 인 경우가 있습니다. 인턴 없이는 두 개의 다른 문자열이 동일하다는 것을 확인하는 데 두 문자열의 모든 문자를 검사해야합니다. 이것은 몇 가지 이유로 천천히 진행됩니다. 문자열의 본래 길이는 O (n)입니다. 일반적으로 시간이 걸리는 여러 메모리 영역에서 읽기가 필요합니다. 읽기가 프로세서 캐시를 가득 채우므로 다른 요구에 사용할 수있는 캐시가 적습니다. 인턴 된 문자열을 사용하면 원래 인턴 작 작업을 수행 한 후에 간단한 개체 동일성 테스트를 수행 할 수 있습니다. 이것은 일반적으로 포인터 동일성 테스트로 구현됩니다. 보통 메모리 참조가없는 단일 기계 명령어 일뿐입니다.

따라서 프로그램에서 두 개의 문자열 리터럴 (따옴표로 묶인 프로그램 소스 코드에 문자 그대로 입력되는 단어)이있는 경우 Python 컴파일러는 자동으로 문자열을 인 텐트하여 둘 다 동일한 위치에 저장합니다 메모리 위치. (이 일은 항상 발생하는 것은 아니며, 이런 일이 발생할 때의 규칙은 매우 복잡하므로 프로덕션 코드에서이 동작에 의존하지 마십시오!)

대화 형 세션에서 두 문자열은 실제로 동일한 메모리 위치에 저장되므로 동일한 ID 를 가지므로 is 연산자는 예상대로 작동합니다. 그러나 다른 문자열 (문자열에 정확히 같은 문자가 포함되어 있어도)을 사용하여 문자열을 구성하면 문자열은 같을 수 있지만 문자열이 같지 않습니다 . 즉, 다른 ID 를 사용합니다. 메모리의 다른 장소에 저장됩니다.


마지막으로 주목해야 할 것은 intern 함수를 사용하여 동일한 문자열에 대한 참조를 얻는 것입니다.

>>> a = intern('a')
>>> a2 = intern('a')
>>> a is a2
True

위에서 지적했듯이, 문자열에 대한 평등을 결정하는 일은하지 않는 것이 좋습니다. 그러나 이것은 당신이 이상한 요구 조건을 가지고 있는지를 아는 데 도움이 될 수 있습니다.

인턴 함수가 내장 함수에서 파이썬 3 용 모듈 sys 로 옮겨졌습니다.


위의 질문에 대한 답은 언어 참조를 인용하지 않았기 때문에 질문은 오래되었지만 질문에 대답하고 있습니다.

실제로 is 연산자는 동일성에 대한 신원 확인 및 == 연산자 점검,

언어 참조에서 :

유형은 객체 동작의 거의 모든 측면에 영향을줍니다. 오브젝트 ID의 중요성조차도 어떤 의미에서 영향을받습니다. 변경 불가능한 유형의 경우, 새 값을 계산하는 조작 은 동일한 유형 및 값을 가진 기존 오브젝트에 대한 참조를 실제로 리턴 할 수 있지만 변경 가능한 오브젝트의 경우에는 허용되지 않습니다 . 예를 들어 a = 1 이후; b = 1, a와 b는 구현에 따라 값이 1 인 동일한 객체를 참조 할 수도 있고 참조하지 않을 수도 있지만 c = []; d = [], c와 d는 새로 생성 된 두 개의 서로 다른 고유 한 빈 목록을 나타냅니다. (c = d = []는 c와 d 모두에 동일한 객체를 할당합니다.)

그래서 위의 명령문에서 "is"로 체크하면 불변 타입 인 문자열이 실패하고 "is"로 체크하면 성공할 것이라고 추론 할 수있다.

int, tuple에도 동일하게 적용됩니다.


자신이하는 일을 잘 모르는 경우 '=='를 사용하십시오. 그것에 대해 조금 더 알고 있으면 '없음'과 같은 알려진 객체에 '사용'을 사용할 수 있습니다.

그렇지 않으면 왜 일이 제대로 돌아 가지 않으며 왜 이런 일이 일어나는지 궁금해집니다.

>>> a = 1
>>> b = 1
>>> b is a
True
>>> a = 6000
>>> b = 6000
>>> b is a
False

어떤 것들이 다른 파이썬 버전 / 구현간에 동일하게 유지되는지 확실하지 않습니다.


저는 이것이 "인턴"문자열이라고 생각합니다. 파이썬은 자바와 최적화 모드로 컴파일 할 때 C와 C ++을 지원합니다.

두 개의 동일한 문자열을 사용하는 경우 두 개의 문자열 객체를 만들어 메모리를 낭비하는 대신 같은 내용의 모든 내부 문자열이 동일한 메모리를 가리 킵니다.

동일한 내용을 가진 두 개의 문자열이 같은 문자열 객체를 가리키고 있기 때문에 파이썬 "is"연산자는 True를 반환합니다. 이것은 자바와 C에서 일어난다.

이것은 메모리 절약에 유용합니다. 다양한 인터프리터와 컴파일러 및 JIT 엔진이 항상 그렇게 할 수는 없으므로 문자열 평등을 테스트하는 데 의존 할 수 없습니다.


is is identity testing, == 는 평등 테스트입니다 ( 파이썬 문서 참조).

대부분의 경우 a is b 이면 a == b 입니다. 그러나 예를 들어 예외가 있습니다.

>>> nan = float('nan')
>>> nan is nan
True
>>> nan == nan
False

그래서, 당신은 신원 테스트를 위해서만 사용할 수 있습니다. 평등 테스트 is 아닙니다.


is 는 메모리 위치를 비교합니다. 이것은 오브젝트 레벨 비교에 사용됩니다.

== 는 프로그램의 변수를 비교합니다. 그것은 가치 수준에서 확인하는 데 사용됩니다.

주소 수준 동등성 검사

== 가치 수준 동등성을 검사합니다.


is 는 정체성 테스트, == 는 평등성 테스트입니다. 코드에서 일어나는 일은 다음과 같이 인터프리터에서 에뮬레이트됩니다.

>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False

그래서, 그들은 똑같지 않다는 것은 당연하지, 그렇지?

다른 말로하면 : is is id(a) == id(b)


is 키워드는 오브젝트 ID에 대한 테스트이고 == 는 값 비교입니다.

is 를 사용하면 객체가 같은 객체 인 경우에만 결과가 true가됩니다. 그러나 == 는 오브젝트의 값이 같을 때마다 true가됩니다.





comparison