Python 얕은 복사와 깊은 복사

2022. 6. 17. 03:12IT

a = 1
b = 2
print(a, b)
1 2
a = 3
print(a, b)
3 2​
[[1, 2, 3]]
[[1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[10, 2, 3], [1, 2, 3], [1, 2, 3]]

파이썬에서 list를 사용하다 이상함을 느꼈다. 다음을 보자.

 

a = []
b = [1, 2, 3]

for i in range(3):
    a.append(b)
    print(a)

a[0][0] = 10
print(a)

 

a라는 배열에 3번에 걸쳐 list b를 append했다. a[0][0]을 출력했더니 그 결과는 다음과 같다.

[[1, 2, 3]]
[[1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[10, 2, 3], [10, 2, 3], [10, 2, 3]]

원하는 결과였던 다음과는 다르다.

[[1, 2, 3]]
[[1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[10, 2, 3], [1, 2, 3], [1, 2, 3]]

 

이것은 python의 리스트가 mutable 변수이기 때문이다. 다음의 표를 참고하자.

 

 

immutable한 class인 int는 다음과 같이 a에 b를 넣고, a를 변경해도 b값은 변하지 않는다. 

a = 1
b = 2
print(a, b)
1 2
a = 3
print(a, b)
3 2

 

 

여기서 list도 immutable한 int 클래스와 같은 방식으로 동작하기를 원한다면 deep copy를 사용하면 된다. 

다음의 예를 보자.

 

import copy
a = []

b = [[1,2],[3,4]]

for i in range(3):
    a.append(copy.deepcopy(b))
    print(a)

a[0][0][0] = 10
print(a)

 

그 결과는 우리가 원하는대로 다음과 같이 출력이 된다.

[[[1, 2], [3, 4]]]
[[[1, 2], [3, 4]], [[1, 2], [3, 4]]]
[[[1, 2], [3, 4]], [[1, 2], [3, 4]], [[1, 2], [3, 4]]]
[[[10, 2], [3, 4]], [[1, 2], [3, 4]], [[1, 2], [3, 4]]]
반응형

'IT' 카테고리의 다른 글

#1/12 아두이노 로봇 HowTo  (0) 2022.11.04
Python obfuscation (난독화)  (0) 2022.07.05
Pyside6 Custom QTextEdit  (0) 2022.05.30
Python Menu & Toolbar  (0) 2022.05.25
Pyside6 window resize & layout  (0) 2022.05.22