developer tip

Python의 "is"연산자 이해

optionbox 2020. 8. 20. 08:12
반응형

Python의 "is"연산자 이해


is연산자는 변수의 값하지만, 인스턴스 자신을 일치하지 않습니다.

그것은 정말로 무엇을 의미합니까?

두 변수에 이름 xy지정하고 두 변수 에 동일한 값을 할당하는 두 개의 변수를 선언 했지만 is연산자를 사용하면 false를 반환합니다 .

설명이 필요합니다. 다음은 내 코드입니다.

x = [1, 2, 3]
y = [1, 2, 3]

print x is y #It prints false!

is운영자가 테스트 하는 것을 오해했습니다 . 두 변수가 동일한 값을 갖는 것이 아니라 두 변수가 동일한 객체를 가리키는 지 테스트 합니다.

is운영자를 위한 문서에서 :

개체 ID에 대한 연산자 isis not테스트 : 동일한 개체 인 x is y경우에만 true 입니다.xy

==대신 연산자를 사용하십시오 .

print x == y

이것은 인쇄합니다 True. x그리고 y두 가지 별도의 목록 :

x[0] = 4
print(y)  # prints [1, 2, 3]
print(x == y)   # prints False

당신이 사용하는 경우 id()기능을 해당를 볼 수 있습니다 xy다른 식별자가 :

>>> id(x)
4401064560
>>> id(y)
4401098192

그러나 할당 y하면 x두 가지 모두 동일한 객체를 가리 킵니다.

>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True

is쇼 모두 동일한 개체가,이 반환됩니다 True.

Python에서 이름은 값을 참조하는 레이블 일뿐입니다 . 동일한 객체를 가리키는 여러 이름을 가질 수 있습니다. is두 개의 이름이 하나의 동일한 객체를 가리키는 지 알려줍니다. ==두 이름이 같은 값을 가진 객체를 참조하는지 알려줍니다.


또 다른 중복 은 두 개의 동일한 문자열이 일반적으로 동일하지 않은 이유를 묻는 것이 었는데, 여기에서는 실제로 대답하지 않았습니다.

>>> 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, 그러나 왜했다 zw동일?

그것은 인터프리터가 자동으로 인턴하는 것이 아니라 컴파일러 폴딩 값입니다.

If the same compile-time string appears twice in the same module (what exactly this means is hard to define—it's not the same thing as a string literal, because r'abc', 'abc', and 'a' 'b' 'c' are all different literals but the same string—but easy to understand intuitively), the compiler will only create one instance of the string, with two references.

In fact, the compiler can go even further: 'ab' + 'c' can be converted to 'abc' by the optimizer, in which case it can be folded together with an 'abc' constant in the same module.

Again, this is something Python is allowed but not required to do. But in this case, CPython always folds small strings (and also, e.g., small tuples). (Although the interactive interpreter's statement-by-statement compiler doesn't run the same optimization as the module-at-a-time compiler, so you won't see exactly the same results interactively.)


So, what should you do about this as a programmer?

Well… nothing. You almost never have any reason to care if two immutable values are identical. If you want to know when you can use a is b instead of a == b, you're asking the wrong question. Just always use a == b except in two cases:

  • For more readable comparisons to the singleton values like x is None.
  • For mutable values, when you need to know whether mutating x will affect the y.

Prompted by a duplicate question, this analogy might work:

# - 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 only returns true if they're actually the same object. If they were the same, a change to one would also show up in the other. Here's an example of the difference.

>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> print x is y
False
>>> z = y
>>> print y is z
True
>>> print x is z
False
>>> y[0] = 5
>>> print z
[5, 2, 3]

is and is not are the two identity operators in Python. is operator does not compare the values of the variables, but compares the identities of the variables. Consider this:

>>> a = [1,2,3]
>>> b = [1,2,3]
>>> hex(id(a))
'0x1079b1440'
>>> hex(id(b))
'0x107960878'
>>> a is b
False
>>> a == b
True
>>>

The above example shows you that the identity (can also be the memory address in Cpython) is different for both a and b (even though their values are the same). That is why when you say a is b it returns false due to the mismatch in the identities of both the operands. However when you say a == b, it returns true because the == operation only verifies if both the operands have the same value assigned to them.

Interesting example (for the extra grade):

>>> del a
>>> del b
>>> a = 132
>>> b = 132
>>> hex(id(a))
'0x7faa2b609738'
>>> hex(id(b))
'0x7faa2b609738'
>>> a is b
True
>>> a == b
True
>>>

In the above example, even though a and b are two different variables, a is b returned True. This is because the type of a is int which is an immutable object. So python (I guess to save memory) allocated the same object to b when it was created with the same value. So in this case, the identities of the variables matched and a is b turned out to be True.

This will apply for all immutable objects:

>>> del a
>>> del b
>>> a = "asd"
>>> b = "asd"
>>> hex(id(a))
'0x1079b05a8'
>>> hex(id(b))
'0x1079b05a8'
>>> a is b
True
>>> a == b
True
>>>

Hope that helps.


As you can check here to a small integers. Numbers above 257 are not an small ints, so it is calculated as a different object.

It is better to use == instead in this case.

Further information is here: http://docs.python.org/2/c-api/int.html


x is y is same as id(x) == id(y), comparing identity of objects.

As @tomasz-kurgan pointed out in the comment below is operator behaves unusually with certain objects.

E.g.

>>> 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


X points to an array, Y points to a different array. Those arrays are identical, but the is operator will look at those pointers, which are not identical.


It compares object identity, that is, whether the variables refer to the same object in memory. It's like the == in Java or C (when comparing pointers).


A simple example with fruits

fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist is newfruitlist )
print ( fruitlist is verynewfruitlist )
print ( newfruitlist is verynewfruitlist )

Output:

True
False
False

If you try

fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist == newfruitlist )
print ( fruitlist == verynewfruitlist )
print ( newfruitlist == verynewfruitlist )

The output is different:

True
True
True

That's because the == operator compares just the content of the variable. To compare the identities of 2 variable use the is operator

To print the identification number:

print ( id( variable ) )

참고URL : https://stackoverflow.com/questions/13650293/understanding-pythons-is-operator

반응형