본문 바로가기
코딩코딩/파이썬

[python] 뮤터블과 이뮤터블 변수 - 왜 튜플과 문자열은 값을 바꿀 수 없을까

by g0n1 2022. 4. 2.
728x90

파이썬 기본 강의에서 항상 나오는 내용 중에 이런 게 있습니다.

리스트는 값을 바꿀 수 있고 튜플은 바꿀 수 없습니다~ 값이 바뀌면 안 되는 경우에는 튜플을 쓰세요~

파이썬으로 처음 배워서인지 그냥 그런갑다~ 하고 넘겼는데 책에서 뮤터블과 이뮤터블의 개념과 함께 나오니까 영 처음 보는 생소한 개념이었습니다. (역시 공부는 근본이 있어야 한다) 그래서 오늘은 크게는 뮤터블 vs 이뮤터블, 작게는 리스트 vs 튜플을 비교하고 알아보려고 합니다.

뮤터블, 이뮤터블의 의미

어떤 객체들의 은 변경할 수 있습니다. 값을 변경할 수 있는 객체들을 가변(mutable) 이라고 합니다.
일단 만들어진 후에 값을 변경할 수 없는 객체들을 
불변(immutable) 이라고 합니다.
...
숫자, 문자열, 튜플(tuple)은 불변이지만, 딕셔너리(dictionary) 와 리스트(list)는 가변입니다.
출처: 파이썬 공식문서
# 코드
a = "hello"
print(a)
print(a[1])
a[1]='a'


# 결과
hello
e
Traceback (most recent call last):
  File "/home/gonlap/git/jungle/week1/mutable.py", line 15, in <module>
    a[1]='a'
TypeError: 'str' object does not support item assignment

hello -> hallo로 변경을 시도해보았습니다.

string은 각 문자를 배열로 쭉 이어놓은 것이기 때문에 위처럼 인덱싱은 가능하지만, 값은 변경할 수 없습니다. 튜플도 마찬가지로 인덱싱은 가능하지만 안의 내용물을 바꿀 수는 없습니다. 이는 파이썬에서 변수에 값을 할당할 때 어떤 일이 일어나는지 알면 이해할 수 있습니다.

변수는 상자가 아니라 화살표

# 코드
# id 함수는 값이 저장된 메모리 주소를 읽어옴
n = 2 
print('n=2 의 id:', id(n))
n = 3
print('n=3 의 id:', id(n))
n = 2
print('n=2 의 id:', id(n))
m = 2
print('m=2 의 id:', id(m))


# 실행 결과
n=2 의 id: 9789024
n=3 의 id: 9789056
n=2 의 id: 9789024
m=2 의 id: 9789024

저도 마찬가지이지만 변수라는 개념이 상자처럼 느껴지곤 합니다. n=2이라는 코드는 n이라고 이름이 붙은 상자에 2를 넣어놓고 n을 호출할 때 마다 상자에서 2를 꺼내는 것처럼 느껴집니다. 하지만 실제로는 n은 메모리속 어딘가에 있는 2라는 숫자의 위치를 가리킬 뿐입니다. m=2를 넣어도 id가 같은 것을 보면 알 수 있습니다.

문자열의 경우에는 실제 값들을 갖고 있는 것이 아니라, 각 문자열들이 저장된 위치들을 모아 갖고 있다고 생각하면 될 것 같습니다. 그래서 우리가 그 값을 인덱싱으로 수정하면 다른 문자열에도 영향이 가기 때문에 파이썬에서 이를 block해놓은 것입니다.

이번엔 변수에 문자열을 할당해보는 실험을 해보겠습니다.

# 코드
a = "hello"
print('a의 id=',id(a))
a = "tello"
print('a의 id=',id(a))
b = "hello"
print('b의 id=',id(b))

# 실행 결과
a의 id= 140084053209968
a의 id= 140084053209776
b의 id= 140084053209968

 

 

 

a와 b에 각각 "hello"라는 문자열을 넣었을 때는, 위에서 했던 실험처럼 같은 곳을 가리키는군요.

튜플은 겉에서 보면 이뮤터블, 속에선 뮤터블

a = ('abc', ['a','b','c'])
print("a의 타입은",type(a))
print("a의 id=",id(a))

a[1].append('d')
print("a의 타입은",type(a))
print("a의 id=",id(a))

# 실행 결과
a의 타입은 <class 'tuple'>
a의 id= 139745882666432
a의 타입은 <class 'tuple'>
a의 id= 139745882666432

tuple은 값을 수정할 수 없는 이뮤터블 변수라고 했지만, 그 안에 있는 뮤터블 변수인 리스트는 수정할 수 있습니다.

알아두면 도움될 정보

  1. 이뮤터블 변수에 대한 접근은 뮤터블 변수에 대한 접근보다 빠르다.(원소 접근시 튜플이 리스트보다 빠르다)
  2. 뮤터블 변수를 바꾸는 것은 이뮤터블 변수를 바꾸는 것에 비해 자원이 덜 소비된다. (이뮤터블 변수를 바꾸려면 수정이든 추가든 복사본을 만드는 과정을 거쳐야 하기 때문이다. )

 

참고한 글

https://www.educative.io/edpresso/what-are-mutable-and-immutable-objects-in-python3

 

What are mutable and immutable objects in Python3?

Creator: Mandava Kranthi Kiran

www.educative.io

https://www.educative.io/edpresso/why-are-strings-in-python-immutable

 

Why are strings in Python immutable?

Creator: Suraj Aravind Bollapragada

www.educative.io

https://www.reddit.com/r/learnpython/comments/7dgi73/why_immutable_are_faster_than_mutable/dpxme92/

 

Why Immutable Are Faster than Mutable?

I have seen tuple give better performance than list.Why like that then??

www.reddit.com

 

728x90

댓글