Programming Languages/Python

[Python] 변수의 mutable과 immutable의 차이

쉬지마 이굥진 2024. 4. 20. 01:46

요새 아침마다 알고리즘 스터디를 하면서, 그날 그날 레벨이 높은 문제가 당첨될수록 내 힘으로 풀지못하고 구글링의 힘을 빌리는 날이 많아지고 있다. 그래서 얼렁뚱땅 푸는 게 아닌 정말 기초부터 탄탄히 하고 싶어서 프로그래머스의 코딩 기초 트레이닝 124 문제를 하루에 되는 대로 많이 풀고 있다.

 

오늘은 문득 문제를 풀면서 이 값은 저장을 해줘야돼 말아야돼? 고민하다가 이 참에 정리를 하고 확실히 한 후 넘어가려고 포스팅 해보려한다.

일단 갓연아 사진 박고 ..

일단 다들 알고 있겠지만.

변수란?

변수(Variable)는 프로그램의 처리 과정에서 데이터를 담아둘 수 있는 메모리의 공간을 의미한다.

하나의 변수에는 하나의 값만 저장할 수 있고, 이 값은 변할 수 있기 때문에 뜻 그대로 '변수' 라고 하는 것이다.

 

 

* 변수 이름 짓는 팁 (권장 사항)

(권장이긴 하지만 이렇게 관습적으로 쓰는 것이니 가독성을 위해 따르는 것이 좋다)

  1. 변수와 메서드 이름은 소문자로 시작하고, 클래스의 첫 글자는 대문자로 시작한다.
    ex) 변수: car, 클래스명: Car
  2. 상수의 이름은 모두 대문자로 한다. 여러 단어로 이루어졌을 경우 '_'로 구분한다.
    ex) PI, MAX_VALUE
  3. 여러 단어로 이루어진 복합 단어일 경우 단어의 첫 번째 단어를 제외한 각 단어의 첫 글자를 대문자로 한다. (= 카멜 표기법)
    ex) personName, calculateArea, StringBuffer
  4. 변수의 이름은 의미 있는 이름으로 하는 것이 좋다.
    ex) String s = "kyungjin" 👉 String name = "kyungjin"
  5. 주의 사항) 변수의 이름에 가장 앞 글자는 숫자가 될 수 없다.
    ex) num1 (o), 1num (error)

 

mutable, immutable

쉽게 간단히 말하면 mutable은 값이 변한다는 뜻이고, immutable은 값이 변하지 않는다는 뜻이다. 자료형마다 mutable인 것도 있고 immutable인 것이 있는데, 왜 그런건지 코드를 통해서 알아봤다.

 

  • 숫자형 (Number) : immutable

x가 1을 가리키고 y가 x를 가리킨다고 했을 때, y에 3을 더하면서 y의 값을 변경하는 순간 y는 4를, x는 1을 가리키게 된다.

 

  • 문자열 (String) : immutable

숫자형과 동일하다. 문자열 y에 'e' 를 추가하더라도 x에는 영향이 가지 않는다.

 

  • 리스트 (List) : mutable

위의 숫자형, 문자열과는 다르다. 리스트 x, y가 있을 때, y에 3을 붙여주면 새로운 리스트가 복사되는 것이 아니라 해당 리스트를 수정한다.

 

  • 튜플 (Tuple) : immutable

튜플 y에 3을 넣어주더라도 x 튜플에는 영향이 없는 것을 볼 수 있다. 

 

  • 딕셔너리 (Dictionary) - mutable

 

 

위의 목록과 사진들을 정리해보면,

숫자, 문자열, 튜플은 변경이 불가능하고 리스트와 딕셔너리는 변경이 가능하다. 

 

 

mutable한 걸 그렇게 쓰고 싶지 않으면 어떻게 하나요?

위 코드들을 보면, y = x 부분에서 y와 x가 같은 주소 값을 가리키고 있다. 이 때 리스트의 [:] (슬라이스)나 deepcopy 함수를 이용하면, 리스트의 복사본을 생성함으로써 같은 객체를 공유하지 않도록 설정할 수 있다. 

[:] 와 deepcopy로 immutable하게 해서 메모리 주소 출력해보기

 

차이점이라고 하면, 슬라이스(:)는 얕은 복사를 수행한다. 이는 복사된 리스트와 원래 리스트가 같은 객체를 참조하고 있을 때 주의해야 한다. 리스트 내에 포함된 객체가 변경되었을 경우, 복사본과 원본에 모두 영향을 미칠 수 있기 때문이다. 반면 이러한 성질은 간단한 리스트 복사에는 유용할 거다 ㅎ

deepcopy() 함수 경우에는 깊은 복사를 수행한다! 모든 객체를 재귀적으로 복사하면서 새로운 객체를 생성하는 로직인데, 이로써 복사본과 원본이 완전히 분리되도록 할 수 있다. 따라서 원본이 변경되도 복사본에는 영향을 주지 않는다.

 

일반적으로 간단한 리스트 복사에는 [:]를 사용하고, 중첩된 구조나 객체를 다룰 땐 copy.deepcopy() 함수를 사용하는 것이 좋다고 한다. (예기치 않은 삽질을 방지하기 위해 😋)


정리

알고리즘 문제를 풀면서 (특히) 리스트와 문자열 사이 mutable 속성과 immutable 속성의 특징을 확실히 몰라서 어이없게 에러를 만들곤 했다. 이 속성에 따라 변수가 함수의 매개변수로 전달될 때 원래 입력 변수값이 변경되는지, 안 되는지 결정하기 때문에 immutable과 mutable 속성을 이해하는 게 매우 중요하다고 느꼈다. 

계속 알고리즘 문제 꾸준히 풀어가면서 체화되도록 훈련해야겠다. 

 


Reference

https://wikidocs.net/32277

https://ledgku.tistory.com/54

https://despiteallthat.tistory.com/2

https://programmerjoon.tistory.com/3