25.5 딕셔너리의 할당과 복사

리스트와 마찬가지로 딕셔너리도 할당과 복사는 큰 차이점이 있습니다. 먼저 딕셔너리를 만든 뒤 다른 변수에 할당합니다.

>>> x = {'a': 0, 'b': 0, 'c': 0, 'd': 0}
>>> y = x

y = x와 같이 딕셔너리를 다른 변수에 할당하면 딕셔너리는 두 개가 될 것 같지만 실제로는 딕셔너리가 한 개입니다.

x와 y를 is 연산자로 비교해보면 True가 나옵니다. 즉, 변수 이름만 다를 뿐 딕셔너리 x와 y는 같은 객체입니다.

>>> x is y
True

x와 y는 같으므로 y['a'] = 99와 같이 키 'a'의 값을 변경하면 딕셔너리 x와 y에 모두 반영됩니다.

>>> y['a'] = 99
>>> x
{'a': 99, 'b': 0, 'c': 0, 'd': 0}
>>> y
{'a': 99, 'b': 0, 'c': 0, 'd': 0}

딕셔너리 x와 y를 완전히 두 개로 만들려면 copy 메서드로 모든 키-값 쌍을 복사해야 합니다.

>>> x = {'a': 0, 'b': 0, 'c': 0, 'd': 0}
>>> y = x.copy()

이제 x와 y를 is 연산자로 비교해보면 False가 나옵니다. 즉, 두 딕셔너리는 다른 객체입니다. 그러나 복사한 키-값 쌍은 같으므로 ==로 비교하면 True가 나옵니다.

>>> x is y
False
>>> x == y
True

딕셔너리 x와 y는 별개이므로 한쪽의 값을 변경해도 다른 딕셔너리에 영향을 미치지 않습니다. 다음과 같이 딕셔너리 y에서 키 'a'의 값을 변경하면 딕셔너리 x는 그대로이고 딕셔너리 y만 바뀝니다.

>>> y['a'] = 99
>>> x
{'a': 0, 'b': 0, 'c': 0, 'd': 0}
>>> y
{'a': 99, 'b': 0, 'c': 0, 'd': 0}

25.5.1  중첩 딕셔너리의 할당과 복사 알아보기

그럼 딕셔너리 안에 딕셔너리가 들어있는 중첩 딕셔너리도 copy 메서드로 복사하면 될까요? 다음과 같이 중첩 딕셔너리를 만든 뒤 copy 메서드로 복사합니다.

>>> x = {'a': {'python': '2.7'}, 'b': {'python': '3.6'}}
>>> y = x.copy()

이제 y['a']['python'] = '2.7.15'와 같이 y의 값을 변경해보면 x와 y에 모두 반영됩니다.

>>> y['a']['python'] = '2.7.15'
>>> x
{'a': {'python': '2.7.15'}, 'b': {'python': '3.6'}}
>>> y
{'a': {'python': '2.7.15'}, 'b': {'python': '3.6'}}

중첩 딕셔너리를 완전히 복사하려면 copy 메서드 대신 copy 모듈의 deepcopy 함수를 사용해야 합니다.

>>> x = {'a': {'python': '2.7'}, 'b': {'python': '3.6'}}
>>> import copy             # copy 모듈을 가져옴
>>> y = copy.deepcopy(x)    # copy.deepcopy 함수를 사용하여 깊은 복사
>>> y['a']['python'] = '2.7.15'
>>> x
{'a': {'python': '2.7'}, 'b': {'python': '3.6'}}
>>> y
{'a': {'python': '2.7.15'}, 'b': {'python': '3.6'}}

이제 딕셔너리 y의 값을 변경해도 딕셔너리 x에는 영향을 미치지 않습니다. copy.deepcopy 함수는 중첩된 딕셔너리에 들어있는 모든 딕셔너리를 복사하는 깊은 복사(deep copy)를 해줍니다.

지금까지 딕셔너리의 다양한 메서드와 응용 방법을 배웠는데, 내용이 다소 어려웠습니다. 딕셔너리의 메서드는 모두 외우지 않아도 되며 파이썬을 사용하다 보면 자연스럽게 익히게 됩니다. 여기서는 딕셔너리에 반복문을 사용하는 방법이 중요합니다. 다른 부분은 필요할 때 다시 돌아와서 찾아보세요.