본문 바로가기
파이썬 - Python

[Python] 파이썬 is와 ==의 차이, python is, ==, identity, equality

by devscb 2022. 11. 15.
반응형

파이썬 is와 ==의 차이, python is, ==, identity, equality



파이썬 is와 ==의 차이


== : 값이 같은지를 비교할떄 사용하는 연산자입니다.
is : 참조되는 메모리 주소가 같은지를 위하 새용하는 연산자입니다.

참조되는 메모리 주소가 같으면, 참조되는 메모리에 해당하는 값은 서로 같지만,
값이 같다고 해서 메모리 주소가 같은것은 아닙니다.

설명이 좀 어려울 수 있는데요, 아래 예제 코드를 보겠습니다.
print 우측에 결과값을 표시하였으며, 주석으로 각 결과에 대해 설명을 합니다.


a = [1,2,3]
b = [1,2,3]
c = a
# a와 b는 담고 있는 값들이 서로 같으나, 메모리 위치가 서로 다릅니다.
print(a == b) #True
print(a is b) #False

# a와 b는 서로 같은 곳을 바라보고 있습니다.
print(a == c) #True
print(a is c) #True


위를 메모리 구조상에서 표현하면 아래와 같습니다.

 


@startuml

package 메모리공간{
component "[1,2,3]" as a1{

}

component "[1,2,3]" as b1{

}

component "변수 a" as a{

}
component "변수 b" as b
component "변수 c" as c
}


a -> a1 : 참조
b -> b1 : 참조
c -> a1 : 참조

center footer https://devscb.tistory.com

@enduml



x is y 가 true가 되기 위한 조건은
각 변수의 id값이 같으면 True가 되기도 합니다.
id 함수를 써서 각 변수들의 id를 출력하여 비교해보면 아래와 같습니다.


a = [1,2,3]
b = [1,2,3]
c = a
# a와 b는 담고 있는 값들이 서로 같으나, 메모리 위치가 서로 다릅니다.
print(id(a), id(b)) #1979894037248 1979890500992
print(a == b) #True
print(a is b) #False

# a와 b는 서로 같은 곳을 바라보고 있습니다.
print(id(a), id(c)) #1979894037248 1979894037248
print(a == c) #True
print(a is c) #True




예외 케이스 : 정수형 값


위에 따르면, 아래 코드는 True, True가 나와야 정상입니다.
왜냐하면 a, b가 각각의 메모리를 할당받고, 각 메모리에 10이라는 값이 들어가게 되기 때문입니다.

a = 10
b = 10
print(a == b)
print(a is b)



그러나 결과는 True, True입니다.
왜 그럴까요?
파이썬에서 메모리 최적화를 위해, -5부터 256까지는 파이썬에서 캐싱하는 싱글턴 오브젝트를 사용하기 때문입니다.
따라서 아래와 같은 코드를 작성하여 실행해보면,

for i in range(-10, 0):
a = i
print("%i: %s" % (i, a is int(str(i))))

for i in range(250, 260):
a = i
print("%i: %s" % (i, a is int(str(i))))



아래와 같은 결과가 나오게 됩니다.

 

-10: False
-9: False
-8: False
-7: False
-6: False
-5: True
-4: True
-3: True
-2: True
-1: True
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

 

 

 

예외 케이스 : nan


python에서는 nan이라는 null과 유사한 객체종류가 있습니다.
이에 대해서는 아래와 같은 결과가 나옵니다.

nan = float('nan')

print(nan is nan) #True
print(nan == nan) #False


nan인지를 체크하기 위해서는 대표적으로 numpy.isnan 메소드를 쓰는 방식이 있습니다.

아래와 같은 방식으로 사용할 수 있습니다.

 

 

import numpy as np

if np.isnan(value) :
    print('nan')

 

 

 

각 자료형에 대한 is 확인 결과


각 자료형에 대한 is를 확인해보면 아래와 같습니다.
list, dictionary에 대해서만 다른 메모리값을 가르키는것을 확인할 수 있었습니다.
아래 결과에서 a is b 가 True가 나오는 점을 미루어 보아,
python 내부적으로 리터럴값을 가리키면 최적화를 하는것으로 보입니다.

#정수
print('==integer==')
a = 10
b = 10
print(a == b) #True
print(a is b) #True

#부동소수
print('==float==')
a = 3.15982489254324342
b = 3.15982489254324342

print(a == b) #True
print(a is b) #True

#복소수
print('==complex==')
a = 1+4j
b = 1+4j

print(a == b) #True
print(a is b) #True

#문자열
print('==string==')
a = 'test'
b = 'test'

print(a == b) #True
print(a is b) #True


#부울
print('==bool==')

a = True
b = True

print(a == b) #True
print(a is b) #True

#리스트
print('==list==')
a = []
b = []

print(a == b) #True
print(a is b) #False

a = [1,2]
b = [1,2]

print(a == b) #True
print(a is b) #False


#튜플
print('==tuple==')
a = ()
b = ()

print(a == b) #True
print(a is b) #True

a = (1,2)
b = (1,2)

print(a == b) #True
print(a is b) #True

#딕셔너리
print('==dictionary==')
a = {}
b = {}

print(a == b) #True
print(a is b) #False

a = {'a':1, 'b':2}
b = {'a':1, 'b':2}

print(a == b) #True
print(a is b) #False




총평


파이썬을 사용하면서 개인적으로 is를 쓰는 경우는 잘 없었던거 같습니다.
제가 보는 코드도 is를 쓰는 경우도 딱히 기억이 나지는 않습니다.
대부분 ==를 쓰게 될 텐데, nan은 isnan을 쓸 수 있도록 꼭 주의해서 써주어야겠습니다.

#python,#is,#==,#identiy,#equality,#파이썬

 

https://devscb.com/post/139

 

[Python] Difference between Python is and ==, python is, ==, identity, equality

Difference between Python is and ==, python is, ==, identity, equality Difference between Python is and ====: This is an operator used when comparing whether v

devscb.com

 

 

728x90
반응형

댓글