mutable과 immutable 객체
파이썬에서 객체의 타입에 따라 mutable(변경 가능)과 immutable(변경 불가능)으로 나뉜다. 이 분류는 객체가 일단 생성된 후 그내용이 변경될 수 있는지 여부에 따라 정해진다.
- immutable : 한 번 생성된 후 그 상태를 변경할 수 없다. 값이 바뀌면 다른 메모리 공간을 할당하여 주소값도 변경해야 한다. 이러한 특성 때문에, 객체에 어떤 변화를 주려고 하면, 객체 자체가 변경되는 것이 아니라 새로운 객체가 생성되어 반환한다.
- bool, int, float, tuple, str, frozenset(불변 세트)
x = 10
y = x
x = x + 1
print(y) # 10, x의 변경이 y에 영향을 주지 않습니다.
- mutable : 생성된 후에 그 내용을 변경할 수 있다. 이러한 객체는 내부의 데이터를 직접 변경할 수 있기 때문에, 객체 자체를 새롭게 만들 필요 없이 값의 추가, 삭제, 수정이 가능하다.
- 리스트(list), 세트(set), 딕셔너리(dict)
my_list = [1, 2, 3]
your_list = my_list
my_list.append(4)
print(your_list) # [1, 2, 3, 4], my_list의 변경이 your_list에 영향을 줍니다.
얕은 복사와 깊은 복사는 mutable 객체만 신경쓰면 된다.
얕은 복사
friends = [1, 2, 3]
li = [[0]*len(friends)]*len(friends)
print(li) # 출력: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
li[0][0] = 1
print(li) # 출력: [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
여기서 li[0][0] = 1은 첫 번째 리스트의 첫 번째 원소를 1로 변경합니다. 그러나 위에 식으로 진행하면 같은 주소값을 복사하여 모든 리스트가 동일한 객체를 참조하고 있으므로, 이 변경은 모든 리스트에 반영된다.
해결 방법
li = [[0]*len(friends) for _ in range(len(friends))]
print(li) # 출력: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
li[0][0] = 1
print(li) # 출력: [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
각각의 내부 리스트가 독립적인 객체가 되게 하려면 리스트 컴프리헨션을 사용하여 각각의 리스트를 독립적으로 생성할 수 있다.
리스트 컴프리헨션(List Comprehension)의 기본 구조
# 기본구조
[expression for item in iterable if condition]
# 간단한 예시: 0부터 9까지 숫자 중에서 짝수만 포함하는 리스트를 생성하고 싶다면
even_numbers = [x for x in range(10) if x % 2 == 0]
print(even_numbers) # 출력: [0, 2, 4, 6, 8]
for 루프와 if 문을 활용하여 보다 간결한 코드로 새로운 리스트를 만든다. 리스트 컴프리헨션은 일반적으로 for 문을 포함한 표현식으로 구성되며, 이를 통해 각 반복에서 리스트의 새 원소를 정의한다.
깊은복사
import copy
lst1 = [[1, 2, 3], [4, 5, 6]]
lst2 = copy.deepcopy(lst1) # 깊은 복사 실행
lst1[1].append(7)
print(lst1) # 출력: [[1, 2, 3, 7], [4, 5, 6]]
print(lst2) # 출력: [[1, 2, 3], [4, 5, 6]]
- 깊은 복사는 다른 메모리 공간에 값을 복사함으로 mutable 객체의 독립성을 유지해 준다.
- 이는 원본 객체와 복사된 객체 간에 아무런 연결 고리가 없도록 만들고 원본 객체의 변경이 복사된 객체에 영향을 미치지 않게 한다.
- 성능 : 깊은 복사는 모든 내용을 새로 복사하므로, 얕은 복사보다 더 많은 메모리와 시간이 소요된다.
- 필요성: 대부분의 일반적인 사용 경우에는 얕은 복사가 충분하다. 깊은 복사는 복잡한 객체 구조를 완전히 독립적으로 복제할 필요가 있을 때 사용된다.
'Python' 카테고리의 다른 글
퍼스트클래스 함수(First Class Function) (0) | 2023.08.30 |
---|