[python] 사전을 복사하고 사본 만 편집하는 방법

누군가 나에게 이것을 설명해 주시겠습니까? 이것은 나에게 이해가되지 않습니다.

사전을 다른 사전에 복사하고 두 번째를 편집하면 둘 다 변경됩니다. 왜 이런 일이 발생합니까?

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = dict1
>>> dict2
{'key2': 'value2', 'key1': 'value1'}
>>> dict2["key2"] = "WHY?!"
>>> dict1
{'key2': 'WHY?!', 'key1': 'value1'}



답변

파이썬은 절대로 객체를 절대로 복사 하지 않습니다 . 을 설정하면 dict2 = dict1객체가 동일한 정확한 dict 객체를 참조하게되므로 변경하면 객체에 대한 모든 참조가 현재 상태의 객체를 계속 참조합니다.

dict을 복사하려면 (드물지만)

dict2 = dict(dict1)

또는

dict2 = dict1.copy()


답변

당신이 할당 할 때 dict2 = dict1, 당신의 사본을 제작하지 않습니다 dict1, 그것은 결과를 dict2위한 또 다른 이름 인 dict1.

사전과 같은 가변 유형을 복사하려면 모듈의 copy/ deepcopy를 사용 하십시오 copy.

import copy

dict2 = copy.deepcopy(dict1)


답변

동안 dict.copy()과는 dict(dict1)복사본을 생성, 그들은 단지입니다 얕은 복사합니다. 깊은 사본 을 원한다면 copy.deepcopy(dict1)필수입니다. 예를 들면 :

>>> source = {'a': 1, 'b': {'m': 4, 'n': 5, 'o': 6}, 'c': 3}
>>> copy1 = x.copy()
>>> copy2 = dict(x)
>>> import copy
>>> copy3 = copy.deepcopy(x)
>>> source['a'] = 10  # a change to first-level properties won't affect copies
>>> source
{'a': 10, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy1
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy2
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy3
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> source['b']['m'] = 40  # a change to deep properties WILL affect shallow copies 'b.m' property
>>> source
{'a': 10, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy1
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy2
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy3  # Deep copy's 'b.m' property is unaffected
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}

Python copy모듈 문서 에서 얕은 사본과 깊은 사본에 대해 :

얕은 복사와 깊은 복사의 차이점은 복합 객체 (목록 또는 클래스 인스턴스와 같은 다른 객체를 포함하는 객체)에만 해당됩니다.

  • 얕은 복사본은 새 복합 개체를 구성한 다음 가능한 한 원본 개체에서 찾은 개체에 참조를 삽입합니다.
  • 딥 카피는 새 복합 객체를 구성한 다음 재귀 적으로 원본에서 찾은 객체의 카피를 복사합니다.

답변

python 3.5 이상에서는 ** unpackaging 연산자를 사용하여 얕게 복사 할 수있는 쉬운 방법이 있습니다. Pep 448에 의해 정의 됨 .

>>>dict1 = {"key1": "value1", "key2": "value2"}
>>>dict2 = {**dict1}
>>>print(dict2)
{'key1': 'value1', 'key2': 'value2'}
>>>dict2["key2"] = "WHY?!"
>>>print(dict1)
{'key1': 'value1', 'key2': 'value2'}
>>>print(dict2)
{'key1': 'value1', 'key2': 'WHY?!'}

** 사전을 새로운 사전에 풀고 dict2에 할당합니다.

각 사전에 고유 한 ID가 있는지 확인할 수도 있습니다.

>>>id(dict1)
 178192816

>>>id(dict2)
 178192600

딥 카피가 필요한 경우 copy.deepcopy () 는 여전히가는 길입니다.


답변

가장 좋고 가장 쉬운 방법 복사본 생성 (A)의 딕셔너리를 모두 파이썬 2.7과 3 입니다 …

단순 (단일 레벨) 사전의 사본을 작성하려면 다음을 수행하십시오.

1. 기존 dict를 가리키는 참조를 생성하는 대신 dict () 메소드 사용 .

my_dict1 = dict()
my_dict1["message"] = "Hello Python"
print(my_dict1)  # {'message':'Hello Python'}

my_dict2 = dict(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

2. 파이썬 사전 의 내장 update () 메소드 사용.

my_dict2 = dict()
my_dict2.update(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

중첩되거나 복잡한 사전의 사본을 작성하려면 다음을 수행하십시오.

일반적인 얕은 복사 및 깊은 복사 작업을 제공하는 내장 복사 모듈을 사용하십시오 . 이 모듈은 Python 2.7과 3 모두에 있습니다. *

import copy

my_dict2 = copy.deepcopy(my_dict1)


답변

사전 이해력으로 새로운 사전을 만들 수도 있습니다. 이렇게하면 사본을 가져 오지 않아도됩니다.

dout = dict((k,v) for k,v in mydict.items())

물론 파이썬> = 2.7에서는 다음을 수행 할 수 있습니다.

dout = {k:v for k,v in mydict.items()}

그러나 이전 버전과의 호환성을 위해서는 최고의 방법이 더 좋습니다.


답변

제공된 다른 솔루션 외에도 **사전을 빈 사전에 통합하는 데 사용할 수 있습니다 ( 예 :

shallow_copy_of_other_dict = {**other_dict}.

이제 “의”얕은 “사본을 갖게됩니다 other_dict.

귀하의 예에 적용 :

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = {**dict1}
>>> dict2
{'key1': 'value1', 'key2': 'value2'}
>>> dict2["key2"] = "WHY?!"
>>> dict1
{'key1': 'value1', 'key2': 'value2'}
>>>

포인터 : 얕고 깊은 사본의 차이점