[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를 잘 모르시는 분들은 다음 글을 봐주세요

medium.com/humanscape-tech/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%98-%EC%8A%A4%ED%8E%98%EC%85%9C-%EB%A9%94%EC%84%9C%EB%93%9C-special-method-2aea6bc4f2b9

 

Medium

 

medium.com

 

우선 첫 번째 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/

 

Python mind-teaser: Make the function return True - Yasoob Khalid

Hi everyone! 👋 I was browsing /r/python and came across this post: The challenge was easy. Provide such an input that if 1 is added to it, it is the instance of the same object but if 2 is added it is not. Solution 1: Custom class The way I personally

yasoob.me