🔍 얕은 복사란?
메모리 주소만 복사
객체의 참조(주소)만 복사되며, 원본 객체와 같은 메모리 공간을 공유함
🔍 깊은 복사란?
객체 자체를 복사
객체 내부의 데이터까지 새로운 메모리 공간에 완전히 복사되어 독립적인 객체가 됨
class TemCls:
def __init__(self, n ,s):
self.number = n
self.str = s
def printClsInfo(self):
print(f'self.number: {self.number}')
print(f'self.str: {self.str}')
# 얕은 복사
tc1 = TemCls(10, 'Hello')
tc2 = tc1 # 주소값 할당
tc1.printClsInfo()
tc2.printClsInfo()
tc2.number = 3.14
tc2.str = 'Bye'
tc1.printClsInfo()
tc2.printClsInfo()
<결과>
self.number: 10
self.str: Hello
self.number: 10
self.str: Hello
self.number: 3.14
self.str: Bye
self.number: 3.14
self.str: Bye
→ 같은 주소를 참조해서 변경된 값으로 출력됨
import copy
tc1 = TemCls(10, 'Hello')
tc2 = copy.copy(tc1)
tc1.printClsInfo()
tc2.printClsInfo()
tc2.number = 3.14
tc2.str = 'Bye'
tc1.printClsInfo()
tc2.printClsInfo()
<결과>
self.number: 10
self.str: Hello
self.number: 10
self.str: Hello
self.number: 10
self.str: Hello
self.number: 3.14
self.str: Bye
→ 독립적인 객체이므로 하나를 바꿔도 다른 하나는 유지됨
scores=[1,2,3,4,5,6]
socresCopy = []
socresCopy = scores
print(f'id(scores):{id(scores)}')
print(f'id(socresCopy):{id(socresCopy)}')
<결과>
id(scores):4445365696
id(socresCopy):4445365696
→ 주소값이 동일함
scores = [1, 2, 3, 4, 5, 6]
socresCopy = []
for s in scores:
socresCopy.append(s)
print(f'id(scores):{id(scores)}')
print(f'id(socresCopy):{id(socresCopy)}')
<결과>
id(scores):4418479232
id(socresCopy):4418580352
→ 주소값이 다름
복사 방식 | 설명 | 예시 |
---|---|---|
얕은 복사 (Shallow Copy) | 최상위 객체만 복사하고 내부 객체는 주소 공유 | a = b, copy.copy() |
깊은 복사 (Deep Copy) | 모든 객체를 재귀적으로 복사해서 완전히 분리 | copy.deepcopy() |
import copy
a = [[1, 2], [3, 4]]
b = copy.copy(a)
c = copy.deepcopy(a)
a[0][0] = 99
print(b) # [[99, 2], [3, 4]] → a 의 주소값을 복사한거라 a 변동시 함께 변동
print(c) # [[1, 2], [3, 4]] → a 의 데이터 자체를 복사한거라 a에 변동줘도 상관없음
👉 중첩된 리스트 같은 복잡한 객체에선 꼭 copy.deepcopy() 쓸 것!!
# 선수의 원본 점수를 이용해서 평균을 출력, 최고 최저를 제외한 평균을 출력하는 프로그램 만들기
import copy
import statistics
player_scores = [8.7, 9.1, 8.9, 9.0, 7.9, 9.5, 8.8, 8.3]
player_scores_deepcopy = copy.deepcopy(player_scores)
# 최고, 최저 제거
player_scores.pop(player_scores.index(max(player_scores)))
player_scores.pop(player_scores.index(min(player_scores)))
print(f'평균값 : {statistics.mean(player_scores_deepcopy)}')
print(f'최고/최저 제외한 평균값 : {statistics.mean(player_scores)}')
id()
로 주소 확인해보는 습관도 좋음