본문 바로가기

Python

[Python] 딕셔너리 복사

문제 인식 : 딕셔너리(Dictionary)를 복사할 필요가 있었다. 이에 '='를 이용해서 복사본을 만들어서 사용하려고 했는데, 복사본의 값을 수정했을 때, 기존 딕셔너리의 값도 수정되는 현상이 있어서 이를 해결할 필요성이 있었다.

문제 해결 : copy모듈의 copy.deepcopy() function을 이용해서 깊은 복사를 해서 또 다른 딕셔너리를 하나 만들어서 다루었다.

 

1. 연산자 '='를 이용하여 딕셔너리를 복사하려 할 때.

test = {'test1' : 1, 'test2' : 2, 'test3' : 3}
test2 = test

if id(test) == id(test2):
    print(True)

print(f"test의 id : {id(test)}")
print(f"test2의 id : {id(test2)}")

# True
# test의 id : 1928795435840	(id 값은 매번 달라질 수 있음)
# test2의 id : 1928795435840 (test와 test2의 id 값이 같다는 것이 핵심, 동일한 object임)

test2['test3'] = 4
print(f"test : {test}")
print(f"test2 : {test2}")

# test : {'test1': 1, 'test2': 2, 'test3': 4}
# test2 : {'test1': 1, 'test2': 2, 'test3': 4}

연산자 '=' 는 딕셔너리의 복사본을 만들지 않는다. 동일한 딕셔너리의 다른 이름을 부여하는 것. 동일한 object이므로 하나를 수정하면 다른 것도 변경된다. 

2. python 내장 copy 메서드을 이용할 때

test = {'test1' : 1, 'test2' : 2, 'test3' : 3}
test3 = test.copy()
print(f"test : {test}")
print(f"test3 : {test3}")
print(f"test의 id : {id(test)}")
print(f"test3의 id : {id(test3)}")
if id(test) != id(test3):
    print(False)

# test : {'test1': 1, 'test2': 2, 'test3': 3}
# test3 : {'test1': 1, 'test2': 2, 'test3': 3}
# test의 id : 2129464308544
# test3의 id : 2129464308800
# False
# python 내장 copy모듈을 사용할 때, 기존 object를 복사해서 새로운 object를 만듦. id값이 달라짐

test3['test3'] = 4
print(f"test : {test}")
print(f"test3 :{test3}")
print(f"test의 id : {id(test)}")
print(f"test3의 id : {id(test3)}")

# test : {'test1': 1, 'test2': 2, 'test3': 3}
# test3 :{'test1': 1, 'test2': 2, 'test3': 4}
# test의 id : 2129464308544
# test3의 id : 2129464308800

# 따라서 새로운 test3의 값을 변경해도, 기존의 test의 값이 변경되지 않는다.

test1 = {'test1' : [1,2,3], 'test2' : [4,5,6], 'test3' : [7,8,9]}
test4 = test1.copy()
print(f"test1 : {test1}")
print(f"test4 :{test4}")
print(f"test1의 id : {id(test1)}")
print(f"test4의 id : {id(test4)}")

test4['test3'][0] = 0
print(f"test1 : {test1}")
print(f"test4 :{test4}")
print(f"test1의 id : {id(test1)}")
print(f"test4의 id : {id(test4)}")

# test1 : {'test1': [1, 2, 3], 'test2': [4, 5, 6], 'test3': [7, 8, 9]}
# test4 :{'test1': [1, 2, 3], 'test2': [4, 5, 6], 'test3': [7, 8, 9]}
# test1의 id : 2129464358528
# test4의 id : 2129464604480
# test1 : {'test1': [1, 2, 3], 'test2': [4, 5, 6], 'test3': [0, 8, 9]}
# test4 :{'test1': [1, 2, 3], 'test2': [4, 5, 6], 'test3': [0, 8, 9]}
# test1의 id : 2129464358528
# test4의 id : 2129464604480

# 다만 딕셔너리 안의 리스트(list), 튜플(tuple), 세트(set)와 같은 컨테이너 객체(container object)가 있는 경우,
# 컨테이너 객체의 값을 변경하면 새로운 딕셔너리에 대한 변경이 기존 딕셔너리에 영향을 미친다.

python 내장 copy 메서드은 얕은 복사 (shallow copy)이다. 이를 해결하기 위해서 깊은 복사(deep copy)를 이용한다.

3. copy모듈의 deepcopy() function을 이용할 때.

import copy
test1 = {'test1' : [1,2,3], 'test2' : [4,5,6], 'test3' : [7,8,9]}
test5 = copy.deepcopy(test1)
print(f"test1 : {test1}")
print(f"test5 : {test5}")
print(f"test1의 id : {id(test1)}")
print(f"test5의 id : {id(test5)}")

# test1 : {'test1': [1, 2, 3], 'test2': [4, 5, 6], 'test3': [7, 8, 9]}
# test5 : {'test1': [1, 2, 3], 'test2': [4, 5, 6], 'test3': [7, 8, 9]}
# test1의 id : 2401639117632
# test5의 id : 2401639491008

test5['test3'][0] = 100
print(f"test1 : {test1}")
print(f"test5 :{test5}")
print(f"test1의 id : {id(test1)}")
print(f"test4의 id : {id(test5)}")

# test1 : {'test1': [1, 2, 3], 'test2': [4, 5, 6], 'test3': [7, 8, 9]}
# test5 :{'test1': [1, 2, 3], 'test2': [4, 5, 6], 'test3': [100, 8, 9]}
# test1의 id : 2401639117632
# tes5의 id : 2401639491008

# deepcopy를 사용할 때는 딕셔너리 안에 다른 객체가 들어있는 경우에도 기존의 딕셔너리와 완전히 독립된
# 복제본을 만들 수 있다.

참고

 

051 파이썬 딕셔너리 파헤치기 - 05. 딕셔너리 복사

#python #파이썬 #딕셔너리 #dictionary #얕은복사 #깊은복사 #shallow_copy #deep_copy #딕셔너리_카피 #...

blog.naver.com