etc./StackOverFlow

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

청렴결백한 만능 재주꾼 2023. 4. 26. 12:46
반응형

질문자 :jottos


'public' 값으로 설정된 Python 프로그램이 있습니다. 조건식에서 비교 var1 is var2 가 실패했지만 var1 == var2 True 반환합니다.

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

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

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



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

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

그래서, 그들이 동일하지 않은 것은 당연하지 않습니까?

즉, a is bid(a) == id(b)


SilentGhost

다른 대답은 정확합니다. is동일성 비교에 사용되는 == 는 동등성 비교에 사용됩니다. 당신이 신경 쓰는 것은 동등성(두 문자열은 같은 문자를 포함해야 함)이기 때문에 이 경우 is 연산자는 단순히 잘못되었으며 대신 ==

그 이유 is 대화식으로 작동하기 때문에 (대부분의) 문자열 리터럴이 기본적으로 인턴십 되기 때문입니다. 위키피디아에서:

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

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

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


Daniel Pryden

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

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


Thomas Owens

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

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

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

intern 함수는 Python 2에서 내장 기능이었지만 Python 3 sys


Jason Baker

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

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


TankorSmash

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

 if x is None: # Some clauses

Null Object (즉, None) 의 인스턴스가 하나만 보장 되기 때문에 이것은 안전합니다.


Gregg Lind

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

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

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

다른 파이썬 버전/구현 간에 일부 사항이 동일하게 유지되는지 확실하지 않습니다.


Mattias Nilsson

python에 대한 제한된 경험에서 is 두 객체를 비교하여 동일한 값을 가진 두 개의 다른 객체와 대조적으로 동일한 객체인지 확인하는 데 사용됩니다. == 는 값이 동일한지 확인하는 데 사용됩니다.

다음은 좋은 예입니다.

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

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


Jack M.

나는 그것이 'is' 비교가 거짓으로 평가될 때 두 개의 별개의 객체가 사용된다는 사실과 관련이 있다고 생각합니다. true로 평가되면 내부적으로 동일한 객체를 사용하고 새 객체를 생성하지 않는다는 것을 의미합니다. 같은 개체를 사용합니다.

이것이 문자열 객체의 값을 비교하기 위해 is 아니라 == 를 사용해야 하는 이유입니다.

 >>> s = 'one' >>> s2 = 'two' >>> s is s2 False >>> s2 = s2.replace('two', 'one') >>> s2 'one' >>> s2 is s False >>>

이 예제에서는 이전에 'one'과 동일했던 다른 문자열 객체인 s2를 만들었습니다. 그러나 인터프리터가 처음에 'one'에 할당하지 않았기 때문에 동일한 객체를 사용하지 않았기 때문에 s , 내가 가지고 있다면 그것들을 같은 객체로 만들었을 것입니다.


meder omuraliev

나는 이것이 "인턴 된"문자열로 알려져 있다고 생각합니다. Python이 이를 수행하고 Java도 수행하며 최적화된 모드에서 컴파일할 때 C 및 C++도 수행합니다.

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

결과적으로 동일한 내용을 가진 두 문자열이 동일한 문자열 객체를 가리키고 있기 때문에 Python "is" 연산자가 True를 반환합니다. 이것은 Java 및 C에서도 발생합니다.

이것은 메모리 절약에만 유용합니다. 다양한 인터프리터, 컴파일러 및 JIT 엔진이 항상 이를 수행할 수는 없기 때문에 문자열 동등성을 테스트하는 데 의존할 수는 없습니다.


Zan Lynx

실제로 is 연산자는 동일성을 확인하고 == 연산자는 동일성을 확인합니다.

언어 참조에서:

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

따라서 위의 문장에서 우리는 변경할 수 없는 유형인 문자열이 "is"로 검사할 때 실패할 수 있고 "is"로 검사할 때 성공할 수 있음을 추론할 수 있습니다.

불변 유형인 inttuple 에도 동일하게 적용됩니다.


Ram

== 연산자는 값 동등성을 테스트합니다. is 연산자는 객체 ID를 테스트하고 Python은 두 객체가 실제로 동일한 객체인지(즉, 메모리의 동일한 주소에 살고 있는지) 테스트합니다.

 >>> a = 'banana' >>> b = 'banana' >>> a is b True

이 예제에서 Python은 하나의 문자열 객체만 생성했으며 ab 모두 이를 참조합니다. 그 이유는 Python이 내부적으로 일부 문자열을 최적화로 캐시하고 재사용하기 때문입니다. 실제로 메모리에는 and b가 공유하는 문자열 '바나나'가 있습니다. 정상적인 동작을 트리거하려면 더 긴 문자열을 사용해야 합니다.

 >>> a = 'a longer banana' >>> b = 'a longer banana' >>> a == b, a is b (True, False)

두 개의 목록을 생성하면 두 개의 객체를 얻습니다.

 >>> a = [1, 2, 3] >>> b = [1, 2, 3] >>> a is b False

이 경우 두 목록은 동일한 요소를 가지고 있지만 동일한 객체가 아니기 때문에 동일하지 않기 때문에 동일하다고 말할 수 있습니다. 두 객체가 동일하면 동일하지만 동일하면 반드시 동일하지는 않습니다.

a 가 객체를 참조하고 b = a 를 할당하면 두 변수 모두 동일한 객체를 참조합니다.

 >>> a = [1, 2, 3] >>> b = a >>> b is a True

X. Wang

is 메모리 위치를 비교합니다. 개체 수준 비교에 사용됩니다.

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

is 어드레스 동등한 수준을 점검

== 값 수준 동등성을 확인합니다.


johnashu

is 는 신원 테스트이고 == 는 평등 테스트입니다( Python 문서 참조).

대부분의 경우 a is b 이면 a == b 입니다. 그러나 다음과 같은 예외가 있습니다.

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

그래서, 당신은 사용할 수 is 신원 시험, 결코 평등 시험.


Ryan

이 질문에 접근할 때 명확하게 해야 하는 기본 개념은 is== 의 차이점을 이해하는 것입니다.

"is"는 메모리 위치를 비교합니다. id(a)==id(b)이면 a is b는 true를 반환하고 그렇지 않으면 false를 반환합니다.

그래서, 우리는 메모리 위치를 비교하기 위해 사용됩니다입니다 말할 수 있습니다. 반면,

== 는 결과 값만 비교한다는 것을 의미하는 동등성 테스트에 사용됩니다. 아래에 표시된 코드는 위의 주어진 이론에 대한 예 역할을 할 수 있습니다.

암호

코드를 보려면 여기를 클릭하세요.

문자열 리터럴(변수에 할당되지 않은 문자열)의 경우 메모리 주소는 그림과 같습니다. 따라서 id(a)==id(b)입니다. 나머지는 자명합니다.


praveen kumar

출처 : http:www.stackoverflow.com/questions/1504717/why-does-comparing-strings-using-either-or-is-sometimes-produce-a-differe

반응형