[Python] is에 대해서, 그리고 재미있는 문제 하나
두비니
·2021. 4. 11. 17:31
1. 비교연산자 'is'에 대하여
is는 python에서 ==과 더불어 python에서 쓸 수 있는 비교문 중 하나입니다.
두 비교문의 차이는 다음과 같습니다.
- is는 변수가 같은 Object(객체)를 가리키면 True
- ==는 변수가 같은 Value(값)을 가지면 True
is는 객체 자체를 본다면, ==는 값을 확인합니다. 이렇게만 하면 감이 안오기때문에 직접 예시로 봅시다.
우선 간단한 ==예시를 보여드리겠습니다.
너무나도 당연한 과정이죠?
그럼 같은 예시를 is를 가지고 해봅시다.
is는 "값"이 같은지 보는게 아니라, "객체"가 같은지 확인해서 그렇습니다. 비록 같은 값이여도, 다른 객체(object)이기 때문에 False를 반환하는 것을 볼 수 있습니다.
이외는 직접 코드를 작성해주시면서 확인하면 좋을 것 같습니다.
2. 한가지 더
사실 이거때문에 글을 썼습니다ㅎㅎ 다음 코드에서 True가 리턴되도록 할 수 있을까요?
def check(x):
if x+1 is 1+x:
return False
if x+2 is not 2+x:
return False
return True
결론적으로는 가능합니다.
이제 이걸 풀 수 있는 방법은 두 가지 정도로 나뉘는데, 차례대로 보도록 합시다.
#1. class 생성
첫 방법은 special method가 포함된 사용자 클래스를 만드는 것입니다.
def check(x):
if x+1 is 1+x:
return False
if x+2 is not 2+x:
return False
return True
class Test(int):
def __add__(self, v):
if v == 1:
return 0
else:
return v
print(check(Test()))
다음과 같이 class를 선언할 경우, special class의 특성때문에 통과할 수 있게 됩니다.
우선 special method를 잘 모르시는 분들은 다음 글을 봐주세요
우선 첫 번째 if문을 봅시다. Test class안에있는 add함수는 special method로 선언된 add이기때문에 더하기의 왼쪽에 오는지, 오른쪽에 오는지에 따라서 값이 바뀌게 됩니다. 자세한 내용은 나누어서 봅시다.
1. 첫 번째 if문
Test() + 1 is 1 + Test()인데, 좌변과 우변을 나누어서 보겠습니다.
Test() + 1은 __add__(self, 1)과 같은 명령어로 처리됩니다. 즉 v의 값이 1이니깐 __add__함수는 0을 리턴합니다. 이렇게 되는 이유는 special method이기 때문이구요.
반면에, 1 + Test()의 경우에는 Test를 부르고 그 뒤에 따로 인자가 없기 때문에 __add__가 애초에 호출되지 않습니다. 따라서 값은 1이 리턴이 되며, 두 값을 다르므로 if문을 건너뜁니다.
2. 두 번째 if문
두 번째 if문도 기본적으로 첫 번째와 똑같이 작동합니다. 다만 다른점이라면 v에 값이 들어와도 2로 들어오기 때문에, 어쨌든 return값은 2가 되서 둘 다 같다고 판단을 하고, 건너뜁니다.
#2. 특별한 정수값
이렇게 복잡하게 코드를 안짜고도 -7을 넣으면 모든게 해결됩니다...ㅎㅎ
def check(x):
if x+1 is 1+x:
return False
if x+2 is not 2+x:
return False
return True
print(check(-7))
일단 설명을 해보겠습니다. Python에서는 -5에서 256까지의 정수가 미리 할당되어 있습니다. 따라서 해당 범위 내에 숫자가 할당을 요청당할 경우, 미리 할당된 개체가 생성되고, 그 외의 숫자들을 그때부터 새로 할당해 주는 것이죠.
이렇게 하는 이유는 성능 향상을 위해서 이런 방법을 택한 것으로 보입니다.
아무튼! 이런 지식을 바탕으로 -7을 넣는 경우, 다음과 같은 과정이 벌어집니다.
1. 첫 번째 if문 (if x+1 is 1+x)
첫 번째 if문에서는 두 개의 -6에 대해서 비교합니다. -6은 미리 할당되어있는 정수들에 포함되지 않기 때문에, 좌변의 -6과 우변의 -6은 각각 다른 object에 할당되게 됩니다. 따라서 if문은 false가 되고, if문을 건너뜁니다.
2. 두 번재 if문 (if x+2 is not 2+x)
반면 두 번째 if문에서는 두 개의 -5에 대해서 비교합니다. -5는 미리 할당되어있는 정수들에 포함되기 때문에, 좌변과 우변의 -5는 둘 다 미리 할당된 id가 할당됩니다. 따라서 if문은 false가 되고, if문을 건너뜁니다.
추가로 255가 안되는 이유는 if문 구성때문에 그렇습니다. 만약 if구성이 반대로 되어있다면, 255 또한 가능하겠죠?
신기한 파이썬세계ㅇㅅㅇ...
참고 : yasoob.me/2019/07/30/python-mind-teaser-make-the-function-return-true/
'Coding_Algorithm > Python' 카테고리의 다른 글
[Python 2] input() 취약점에 대하여 (0) | 2021.05.17 |
---|---|
[Python] 레퍼런스(reference)에 대해서 (0) | 2021.04.10 |
[Python 함수정리] 숫자 반올림하고싶을때 :: round (0) | 2020.03.19 |
[repl.it] 4.7. For: Number of zeros Solutions/풀이 (0) | 2020.03.17 |
Python에서 for문으로 감산하기 (0) | 2019.05.21 |