Re: 26.7 퀴즈 6번 질문 드립니다.
, 도장_ 관리자님이 작성문제에 오류가 있었습니다.
코딩 도장 온라인에서는 문제를 바로 수정해서 반영하고,
도서에서는 다음 쇄에 반영할 예정입니다.
6번 문제에서는
-. "모두" 삭제
-. 정답에서 c 삭제
-. 해설에 is, is not을 사용하면 안 됩니다. 문구 추가
의 수정 사항을 반영했습니다.
{i for i in range(10) if i is not 2 and i is not 7}
예시 c의 코드는 우연히 올바른 결과가 나오는 것으로 보이는 코드입니다.
{i for i in range(-10, 1) if i is not -2 and i is not -7}
{0, -10, -9, -8, -7, -6, -5, -4, -3, -1}
음수로 바꾸면 동작하지 않습니다. -2, -7이 빠져야 하지만 -7은 들어갑니다.
id 함수로는 객체 ID를 구할 수 있습니다.
>>> id(-10)
2245116850320
>>> id(-10)
2245116850384
>>> id(-10)
2245116850256
>>> id(-10)
2245116850352
>>> id(-10)
2245116850288
>>>
2245116850320
>>> id(-10)
2245116850384
>>> id(-10)
2245116850256
>>> id(-10)
2245116850352
>>> id(-10)
2245116850288
>>>
id(-10)을 하면 음수에 대해서 객체를 끊임없이 새로 생성하고 있습니다.
>>> a = -10
>>> a is -10
False
>>>
>>> a is -10
False
>>>
객체의 변경과 상관없이 -10을 넣으면 매번 id 값이 바뀌니까
한 번만 대입해도 결과는 항상 False입니다.
>>> id(-5)
140705962359680
>>> id(-5)
140705962359680
>>> id(-5)
140705962359680
>>> b = -5
>>> id(b)
140705962359680
>>> id(-5)
140705962359680
>>> b is -5
True
>>>
140705962359680
>>> id(-5)
140705962359680
>>> id(-5)
140705962359680
>>> b = -5
>>> id(b)
140705962359680
>>> id(-5)
140705962359680
>>> b is -5
True
>>>
-5는 파이썬에서 내부적으로 캐시를 하고 있습니다.
그래서 id(-5)를 여러 번 실행해도 항상 동일한 객체를 반환합니다.
그래서 b is -5는 True가 됩니다.
>>> b = -10
>>> b is -10
False
>>> b = -5
>>> b is -5
True
>>>
>>> b is -10
False
>>> b = -5
>>> b is -5
True
>>>
결국 b는 언제든 -5를 할당하면 동일 객체값이 되어서 True가 나옵니다.
>>> id(1000)
2395666369968
>>> id(1000)
2395666370288
>>> id(1000)
2395666370064
>>> d = 1000
>>> d is 1000
False
>>>
2395666369968
>>> id(1000)
2395666370288
>>> id(1000)
2395666370064
>>> d = 1000
>>> d is 1000
False
>>>
정수 1000일 때도 똑같습니다.
파이썬은 내부적으로 [-5, 256]을 immutable object로 캐시하고 있다고 합니다.
왜 이런 구현을 따르는지는 모릅니다.
-5, 256 범위에서는 is가 동작하는 것처럼 보입니다.
>>> {i for i in range(-10, 1) if i is not -2 and i is not -3}
{0, -10, -9, -8, -7, -6, -5, -4, -1}
{0, -10, -9, -8, -7, -6, -5, -4, -1}
-2, -7일 때는 -7이 들어갔지만, -2, -3으로 바꾸면 -2, -3이 빠진 세트를 만들 수 있는 이유도 immutable object 캐시 때문입니다.
파이썬에서는 숫자도 객체이므로 매번 새로 생성되어야 합니다. 다만, 자주 쓰이는 작은 숫자 값의 범위에 대해서 매번 새로 생성하면 비효율적이니까 [-5, 256]의 범위에 대해서는 불변 객체(immutable object)로 만들어서 미리 준비한 객체를 제공하는 것입니다.
이 때문에 id(-5)나 id(5)는 항상 같은 같이 나오고, 이 범위의 값에 대해서는 is, is not을 대입했을 때 값을 비교하는 ==, !=과 같은 결과가 나오게 됩니다. 이는 우연에 의한 결과이므로 결과는 바르게(?) 나오는 것처럼 보이지만, 정답이 아닙니다.
오류를 발견해주셔서 감사합니다.
support@dojang.io로 메일을 주시면 도서 증정을 드리겠습니다.
감사합니다.