[Python] 얕은 복사 & 깊은 복사

Jimin_Note·7일 전
0

[Python]

목록 보기
36/40
post-thumbnail

🔍 얕은 복사란?

메모리 주소만 복사
객체의 참조(주소)만 복사되며, 원본 객체와 같은 메모리 공간을 공유함


🔍 깊은 복사란?

객체 자체를 복사
객체 내부의 데이터까지 새로운 메모리 공간에 완전히 복사되어 독립적인 객체가 됨


✅ 예제

1.1 얕은 복사

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

→ 같은 주소를 참조해서 변경된 값으로 출력됨


1.2 깊은 복사

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

→ 독립적인 객체이므로 하나를 바꿔도 다른 하나는 유지됨

2.1 얕은 복사

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

→ 주소값이 동일함

2.2 깊은 복사

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)}')

✅ 회고

  • 단순 대입은 얕은 복사를! 중첩 구조 or 변경 영향 차단하고 싶다면 깊은 복사필수!
  • 디버깅 시에는 id()로 주소 확인해보는 습관도 좋음
profile
Hello. I'm jimin:)

0개의 댓글