[python] ‘==’또는 ‘is’를 사용하여 문자열을 비교하면 때때로 다른 결과가 생성되는 이유는 무엇입니까?

두 개의 변수가 value로 설정된 Python 프로그램이 있습니다 'public'. 조건부 표현식에서는 비교 var1 is var2에 실패하지만 변경하면을 var1 == var2반환합니다 True.

이제 파이썬 인터프리터를 열고 동일한 “is”비교를 수행하면 성공합니다.

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

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



답변

is신원 테스트, ==평등 테스트입니다. 코드에서 발생하는 일은 다음과 같이 인터프리터에서 에뮬레이트됩니다.

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

그들이 같지 않은 것도 당연합니다.

즉 : is는 ISid(a) == id(b)


답변

: 여기에 다른 대답이 올바른지 is에 사용되는 신원 반면, 비교 ==에 사용되는 평등의 비교. 당신이 신경 쓰는 것은 평등 (두 문자열은 같은 문자를 포함해야 함)이기 때문에이 경우 is연산자는 단순히 틀리므로 ==대신 사용해야합니다 .

is대화식으로 작동 하는 이유 는 (대부분의) 문자열 리터럴이 기본적 으로 포함 되기 때문입니다. Wikipedia에서 :

내부 문자열은 문자열 비교 속도를 높이며, 때로는 문자열 키가있는 해시 테이블에 의존하는 응용 프로그램 (예 : 컴파일러 및 동적 프로그래밍 언어 런타임)의 성능 병목 현상이 발생합니다. 인턴없이 두 개의 서로 다른 문자열이 같은지 확인하려면 두 문자열의 모든 문자를 검사해야합니다. 여러 가지 이유로 느립니다. 문자열 길이가 본질적으로 O (n)입니다. 일반적으로 여러 메모리 영역에서 읽기가 필요하며 시간이 걸립니다. 읽기는 프로세서 캐시를 채우므로 다른 요구에 사용할 수있는 캐시가 줄어 듭니다. 인턴 된 문자열을 사용하면 원래 인턴 작업 후에 간단한 객체 식별 테스트로 충분합니다. 이것은 일반적으로 포인터 평등 테스트로 구현됩니다.

따라서 동일한 값을 가진 프로그램에 두 개의 문자열 리터럴 (문자 그대로 프로그램 소스 코드에 따옴표로 묶은 단어)이 있으면 파이썬 컴파일러는 자동으로 문자열을 인턴하여 문자열을 동일하게 저장합니다 메모리 위치. ( 항상 이러한 상황이 발생하는 것은 아니며 이러한 상황이 발생하는 규칙은 매우 복잡하므로 프로덕션 코드에서이 동작에 의존하지 마십시오!)

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


답변

is동안 키워드는 개체 식별을위한 테스트입니다 ==값 비교입니다.

을 사용 is하면 객체가 동일한 객체 인 경우에만 결과가 적용됩니다. 그러나 ==개체의 값이 같을 때마다 적용됩니다.


답변

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

>>> from sys import intern
>>> a = intern('a')
>>> a2 = intern('a')
>>> a is a2
True

위에서 지적했듯이 is문자열의 동등성을 결정 하는 데 사용해서는 안됩니다 . 그러나 이것은 당신이 어떤 이상한 요구 사항을 가지고 있는지 아는 데 도움이 될 수 있습니다 is.

점을 유의 intern함수 파이썬 (2)에 내장되도록 사용되지만 이동되었다 sys파이썬 3 모듈.


답변

is신원 테스트, ==평등 테스트입니다. 이것이 의미하는 바 is는 두 가지가 같은 것이거나 동등한 지 여부를 확인하는 방법 입니다.

간단한 person물건 이 있다고 가정 해보십시오 . 이름이 ‘잭’이고 ’23’년 된 경우 다른 23 세의 잭과 동일하지만 같은 사람이 아닙니다.

class Person(object):
   def __init__(self, name, age):
       self.name = name
       self.age = age

   def __eq__(self, other):
       return self.name == other.name and self.age == other.age

jack1 = Person('Jack', 23)
jack2 = Person('Jack', 23)

jack1 == jack2 #True
jack1 is jack2 #False

그들은 같은 나이이지만 같은 사람이 아닙니다. 문자열은 다른 문자열과 동일 할 수 있지만 동일한 개체가 아닙니다.


답변

이것은 부수적이지만 관용적 파이썬에서는 다음과 같은 것을 종종 볼 수 있습니다.

if x is None:
    # some clauses

Null Object의 인스턴스 (즉, None)가 하나 보장 되므로 안전 합니다.


답변

무엇을하고 있는지 잘 모르겠 으면 ‘==’를 사용하십시오. 그것에 대해 조금 더 알고 있다면 ‘없음’과 같은 알려진 객체에 ‘is’를 사용할 수 있습니다.

그렇지 않으면 왜 작동하지 않는지, 왜 이런 일이 발생하는지 궁금해 할 것입니다.

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

다른 파이썬 버전 / 구현 사이에서 동일한 것이 유지되는지 확실하지 않습니다.