Python

[Python] 얕은 복사 (Shallow copy)

비번변경 2023. 12. 18. 15:00

개요

2023.12.14 - [Python] 불변 객체 (Immutable)

2023.12.15 - [Python] 가변 객체 (Mutable)

위 두 개 글에서 불변 객체와 가변 객체에 대해 정리했는데, 이 글에서는 얕은 복사에 대해 정리해보려고 한다.

 

 

얕은 복사

얕은 복사(Shallow copy)란 객체의 참조값, 주소값만 복사하는 것을 의미한다. 객체의 주소값을 복사하기 때문에 복사된 값에 변경이 발생하면 복사한 값도 영향을 받아 두 변수 간에 독립성이 성립하지 않게 되는 특징이 있다.

다만, 변수의 독립성과 관련해서는 참조한 객체가 가변 객체인 경우에만 문제가 되며, 관련해서는 사실 2023.12.15 - [Python] 가변 객체 (Mutable)에서 살펴보았다.

따라서 이 글에서는 얕은 복사를 수행하는 방법을 위주로 정리한다.

 

1. 할당(=) 연산자 사용

a = "python2"
b = a
print(f'a={a}, id(a)={id(a)}')
print(f'b={b}, id(b)={id(b)}')

print('\n--값 갱신--')
a = "python3"
print(f'a={a}, id(a)={id(a)}')
print(f'b={b}, id(b)={id(b)}')

 

 

2. 슬라이싱

슬라이싱을 이용하여 가변 객체를 복사하면 복사한 변수가 참조하는 주소값이 달라져 얕은 복사가 아닌 것처럼 보인다.

a = ["python2", ["python3"]]
b = a[:]

print(f"""a={a}, id(a)={id(a)}""")
print(f"""b={b}, id(b)={id(b)}""")

하지만 각 원소의 주소값까지 확인해보면 가변 객체를 참조하는 원소는 같은 주소값을 참조하고 있는 것을 확인할 수 있다.

따라서 가변 객체인 원소의 상태를 변경하면, 복사한 변수에도 영향을 미치는 것을 알 수 있다.

a = ["python2", ["python3"]]
b = a[:]

print(f"""a={a}, id(a)={id(a)}""")
print(f"""b={b}, id(b)={id(b)}""")

print('\n--값 갱신--')
a.append(22)
a[1].append('python4')
print(f"""a={a}, id(a)={id(a)}""")
print(f"""b={b}, id(b)={id(b)}""")

이런 경우에도 얕은 복사로 취급하는데, 그림으로 표현하면 아래와 같다.

 

3. copy 함수 사용

객체 클래스가 제공하는 copy 함수는 슬라이싱을 하는 것과 동일하게 동작한다.

a = ["python2", ["python3"]]
b = a.copy()

print(f"""a={a}, id(a)={id(a)}""")
print(f"""b={b}, id(b)={id(b)}""")

print('\n--값 갱신--')
a.append(22)
a[1].append('python4')
print(f"""a={a}, id(a)={id(a)}""")
print(f"""b={b}, id(b)={id(b)}""")

 

 

4. copy 모듈의 copy 함수 사용

copy 모듈의 copy 함수 또한 슬라이싱할 때와 동일하게 동작한다.

from copy import copy

a = ["python2", ["python3"]]
b = copy(a)

print(f"""a={a}, id(a)={id(a)}""")
print(f"""b={b}, id(b)={id(b)}""")

print('\n--값 갱신--')
a.append(22)
a[1].append('python4')
print(f"""a={a}, id(a)={id(a)}""")
print(f"""b={b}, id(b)={id(b)}""")

 

 

불변 객체의 경우

불변 객체인 경우, 객체의 상태를 변경하면 항상 참조하는 메모리의 주소가 달라진다.

 

 

참고 문서

[파이썬/Python] 얕은 복사(Shallow copy)와 깊은 복사(deep copy)에 대한 완벽 정리

[python] 파이썬 얕은복사, 깊은복사 (copy, deepcopy, [:], =) 총 정리

 

728x90