immutable과 hashable의 관계

CodingJoker·2024년 12월 9일

각 용어의 개념

mutable과 immutable 하다는 표현들은 코딩 공부를 하다보면 자주 보게된다.
이들의 뜻은 간단히 객체의 '변경 가능'과 '변경 불가능'을 의미한다.
하지만 단순하게 변경 가능 여부로 정의하기에는 조금 아쉬운 설명이다.
따라서 조금 더 디테일하게 알아보도록 하자.

종류
mutablelist, set, dictionary
immutableint, float, bool, str, tuple

immutable 객체

a = 1
print(id(a))
a = 2
print(id(a))

예를 들어 a = 1이라고 작성했을 때, a라는 변수가 1이라는 객체를 참조한다.
그런다음 a = 2로 변경했을 때, a는 2라는 객체를 참조한다.
immutable한 1 (int)을 바꾸지 못하기 때문에 새로운 메모리 공간을 확보하고 a가 2를 참조하도록 하는 것이다.
print문은 주소값이 찍힐텐데 두 값이 다른 것을 확인할 수 있을 것이다.

immutable객체는 변경하지 못한다고 했을 때, 문자열에 대한 의문이 있을 수 있다.
replace같은 함수나 +를 통해 값을 변경할 수 있기 때문이다.
이는 기존 객체를 변경하는 것이 아니고, 값을 복사하여 새로운 메모리 공간에 할당해주는 것이다.
이들도 마찬가지로 변경 전 후의 id값을 찍어보면 다른 것을 알 수 있다.

mutable 객체

lst = [1, 2, 3]
print(id(lst))
lst[1] = 4		# [1, 4, 3]
print(id(lst))
lst.append(6)	# [1, 4, 3, 6]
print(id(lst))

list는 mutable한 객체이다. 따라서 인덱스를 이용하여 값을 변경하거나, append로 값을 추가 하여도 주소값에는 변화가 없는 것을 확인할 수 있다.

hashable

hashable이라는 개념은 '값의 비교'를 위해 존재한다.
hash라는 함수는 hashable object가 인자로 들어갔을 때 어떤 정수 하나를 반환해준다.

hash function을 거치면 같은 객체인지 다른 객체인지 빠르게 비교가 가능해진다.

hash의 값이 도중에 변경되면 안되기 때문에, key로 immutable한 값을 요구한다.
그러면 모든 immutable한 객체는 hashable한지에 대한 생각이 떠오를 수 있는데,
결론적으로 이는 그렇지 않다고 할 수 있고, 자세한 얘기는 뒤에 설명한다.

중복여부를 판단하는 set이나 dictinary의 key들이 hashable해야한다.

immutable 객체의 예외

tp = (1, 2, 3)
tp[1] = 4
# TypeError: 'tuple' object does not support item assignment

tuple은 immutable하므로 일반적으로 변경할 수 없다.

tp = (0, 1)
print(id(tp))
tp += (2,)    # (0, 1, 2)
print(id(tp))

다만 위와 같이 str 처럼 복사를 통한 새로운 값을 할당하여 변경하는 것은 가능하다.
새로운 주소를 가지기 때문에 print값이 다른 것을 확인할 수 있다.

그러나 예외의 상황이 있다.

tp2 = (0, [1, 2, 3])
print(id(tp2))
tp2[1].append(4)    # (0, [1, 2, 3, 4])
print(id(tp2))

위와 같이 tuple의 값으로 mutable한 list를 가질 수 있다.
tp2[1]는 mutable하므로 값을 추가할 수 있다.
tp2가 참고하는 값을 변경시키는 것이 아니므로 이런 변경이 가능하고 주소값 또한 변경되지 않은 것을 확인할 수 있다.

모든 immutable한 객체는 hashable한지?

앞에서 말한 list를 가지는 tuple은 immutable한 동시에 값의 변경이 일어날 수 있다.
hashable의 key 값으로는 변경되는 것이 오면 안되기 때문에 위 같은 경우의 tuple은 hashable하지 않다고 할 수 있다. (immutable한 값만 가지는 tuple은 hashable하다고 할 수 있다.)

profile
어제보다 지식 1g 쌓기

0개의 댓글