얕은 복사, 딥 카피 및 일반 할당 작업의 차이점은 무엇입니까?


210
import copy

a = "deepak"
b = 1, 2, 3, 4
c = [1, 2, 3, 4]
d = {1: 10, 2: 20, 3: 30}

a1 = copy.copy(a)
b1 = copy.copy(b)
c1 = copy.copy(c)
d1 = copy.copy(d)


print("immutable - id(a)==id(a1)", id(a) == id(a1))
print("immutable - id(b)==id(b1)", id(b) == id(b1))
print("mutable - id(c)==id(c1)", id(c) == id(c1))
print("mutable - id(d)==id(d1)", id(d) == id(d1))

다음과 같은 결과가 나타납니다.

immutable - id(a)==id(a1) True
immutable - id(b)==id(b1) True
mutable - id(c)==id(c1) False
mutable - id(d)==id(d1) False

심도 복사를 수행하는 경우 :

a1 = copy.deepcopy(a)
b1 = copy.deepcopy(b)
c1 = copy.deepcopy(c)
d1 = copy.deepcopy(d)

결과는 같습니다 :

immutable - id(a)==id(a1) True
immutable - id(b)==id(b1) True
mutable - id(c)==id(c1) False
mutable - id(d)==id(d1) False

할당 작업을 수행하는 경우 :

a1 = a
b1 = b
c1 = c
d1 = d

결과는 다음과 같습니다.

immutable - id(a)==id(a1) True
immutable - id(b)==id(b1) True
mutable - id(c)==id(c1) True
mutable - id(d)==id(d1) True

누군가가 사본 사이의 차이점을 정확히 설명 할 수 있습니까? 가변 및 불변 개체와 관련이 있습니까? 그렇다면 설명해 주시겠습니까?

답변:


364

일반 할당 작업은 단순히 새 변수를 기존 객체를 향하게합니다. 문서는 얕은 및 깊은 사본의 차이를 설명 :

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

  • 얕은 복사본은 새 복합 개체를 구성한 다음 가능한 한 원본 개체에서 찾은 개체에 참조를 삽입합니다.

  • 딥 카피는 새 복합 객체를 구성한 다음 재귀 적으로 원본에서 찾은 객체의 카피를 복사합니다.

다음은 약간의 데모입니다.

import copy

a = [1, 2, 3]
b = [4, 5, 6]
c = [a, b]

일반 할당 작업을 사용하여 복사 :

d = c

print id(c) == id(d)          # True - d is the same object as c
print id(c[0]) == id(d[0])    # True - d[0] is the same object as c[0]

얕은 사본 사용하기 :

d = copy.copy(c)

print id(c) == id(d)          # False - d is now a new object
print id(c[0]) == id(d[0])    # True - d[0] is the same object as c[0]

딥 카피 사용 :

d = copy.deepcopy(c)

print id(c) == id(d)          # False - d is now a new object
print id(c[0]) == id(d[0])    # False - d[0] is now a new object

5
어설 션이 얕은 사본과 동일합니까?
deeshank

35
@Dshank No. 얕은 사본은 새로운 객체를 구성하는 반면 할당은 단순히 새로운 객체를 기존 객체를 가리 킵니다. 기존 객체를 변경하면 두 변수 (할당 포함)에 영향을줍니다.
grc

13
@grc "기존 객체에 대한 모든 변경 사항은 두 변수에 모두 영향을 미칩니다 (할당 포함)"-이 문장은 가변 객체에만 적용되며 string, float, tuples와 같은 불변 유형에는 해당되지 않습니다.
Neerav

1
@grc하지만 예를 시도했다 (I 여기에 새로운 라인을 제거합니다.) 여전히 표시 . 그러나 변경 가능한 목록입니다. list_=[[1,2],[3,4]] newlist = list_.copy() list_[0]=[7,8] print(list_) print(newlist)newlist[[1, 2], [3, 4]]list_[0]
Alston

1
@Stallman list_[0]은 변경 가능하지만 변경 / 수정하지 않았습니다. 시도 list_[0].append(9)하거나 list_[0][0] = 7대신하십시오.
grc

46

불변 개체의 경우 데이터가 변경되지 않기 때문에 복사가 필요하지 않으므로 Python은 동일한 데이터를 사용합니다. ID는 항상 같습니다. 변경 가능한 객체의 경우 잠재적으로 변경 될 수 있으므로 [얕은] 복사는 새 객체를 만듭니다.

딥 카피는 중첩 구조와 관련이 있습니다. 리스트리스트가있는 경우 copies중첩리스트도 딥 카피하므로 재귀 적 사본입니다. 복사 만하면 새로운 외부 목록이 있지만 내부 목록은 참조입니다.

과제는 복사되지 않습니다. 단순히 이전 데이터에 대한 참조를 설정합니다. 따라서 동일한 내용으로 새 목록을 만들려면 복사해야합니다.


With just copy, you have a new outer list but inner lists are references.내부 목록의 경우 복사 된 항목이 원본 목록의 영향을 받습니까? 내가 좋아하는 목록의 목록을 작성 list_=[[1,2],[3,4]] newlist = list_.copy() list_[0]=[7,8]하고, newlist그래서 참조입니다 내부 목록에 않습니다, 유물 같은?
Alston

1
@Stallman 여기에서 참조 목록을 변경하지 않고 새 목록을 만들고 사본 중 첫 번째 항목으로 지정하면됩니다. 시도list_[0][0] = 7
perreal

20

변경 불가능한 객체의 경우 복사본을 만들면 변경되지 않으므로 의미가 없습니다. 변경 가능한 객체의 경우 assignment, copydeepcopy다르게 동작합니다. 각각의 예에 대해 이야기 해 봅시다.

할당 작업은 단순히 소스의 참조를 대상에 할당합니다.

>>> i = [1,2,3]
>>> j=i
>>> hex(id(i)), hex(id(j))
>>> ('0x10296f908', '0x10296f908') #Both addresses are identical

이제 ij기술적으로 동일한 목록을 의미합니다. 모두 ij같은 메모리 주소를 가지고있다. 둘 중 하나에 대한 업데이트는 다른 사람에게 반영됩니다. 예 :

>>> i.append(4)
>>> j
>>> [1,2,3,4] #Destination is updated

>>> j.append(5)
>>> i
>>> [1,2,3,4,5] #Source is updated

반면에 copydeepcopy변수의 새 복사본을 생성합니다. 따라서 원래 변수에 대한 변경 사항은 복사 변수에 반영되지 않으며 그 반대도 마찬가지입니다. 그러나 copy(shallow copy)중첩 된 객체의 복사본을 만들지 말고 중첩 된 객체의 참조 만 복사하면됩니다. Deepcopy는 중첩 된 모든 객체를 재귀 적으로 복사합니다.

몇 가지 예는 다음의 행동을 설명하는 copy과를 deepcopy:

다음을 사용하는 단순 목록 예 copy:

>>> import copy
>>> i = [1,2,3]
>>> j = copy.copy(i)
>>> hex(id(i)), hex(id(j))
>>> ('0x102b9b7c8', '0x102971cc8') #Both addresses are different

>>> i.append(4)
>>> j
>>> [1,2,3] #Updation of original list didn't affected copied variable

다음을 사용하는 중첩 목록 예제 copy:

>>> import copy
>>> i = [1,2,3,[4,5]]
>>> j = copy.copy(i)

>>> hex(id(i)), hex(id(j))
>>> ('0x102b9b7c8', '0x102971cc8') #Both addresses are still different

>>> hex(id(i[3])), hex(id(j[3]))
>>> ('0x10296f908', '0x10296f908') #Nested lists have same address

>>> i[3].append(6)
>>> j
>>> [1,2,3,[4,5,6]] #Updation of original nested list updated the copy as well

다음을 사용하는 단순 목록 예 deepcopy:

>>> import copy
>>> i = [1,2,3]
>>> j = copy.deepcopy(i)
>>> hex(id(i)), hex(id(j))
>>> ('0x102b9b7c8', '0x102971cc8') #Both addresses are different

>>> i.append(4)
>>> j
>>> [1,2,3] #Updation of original list didn't affected copied variable

다음을 사용하는 중첩 목록 예제 deepcopy:

>>> import copy
>>> i = [1,2,3,[4,5]]
>>> j = copy.deepcopy(i)

>>> hex(id(i)), hex(id(j))
>>> ('0x102b9b7c8', '0x102971cc8') #Both addresses are still different

>>> hex(id(i[3])), hex(id(j[3]))
>>> ('0x10296f908', '0x102b9b7c8') #Nested lists have different addresses

>>> i[3].append(6)
>>> j
>>> [1,2,3,[4,5]] #Updation of original nested list didn't affected the copied variable    

18

그래픽 예제에서 다음 코드가 어떻게 실행되는지 봅시다 :

import copy

class Foo(object):
    def __init__(self):
        pass


a = [Foo(), Foo()]
shallow = copy.copy(a)
deep = copy.deepcopy(a)

여기에 이미지 설명을 입력하십시오


5

a, b, c, d, a1, b1, c1 및 d1은 메모리의 객체에 대한 참조이며, ID로 고유하게 식별됩니다.

할당 작업은 메모리의 객체에 대한 참조를 가져와 해당 참조를 새 이름에 할당합니다. c=[1,2,3,4]는 4 개의 정수를 포함하는 새 목록 객체를 만들고 해당 객체에 대한 참조를에 할당하는 할당 c입니다. 동일한 객체에 대한 동일한 참조를c1=c 가져와 할당하는 할당입니다 c1. 목록은 변경 가능하기 때문에 목록을 통해 액세스하는지 c또는에 관계없이 해당 목록에서 발생하는 모든 내용이 표시됩니다 c1. 둘 다 동일한 객체를 참조하기 때문입니다.

c1=copy.copy(c)새 목록을 만들고 새 목록에 대한 참조를에 할당하는 "얕은 복사본"입니다 c1. c여전히 원본 목록을 가리 킵니다. 따라서에서 목록을 수정 c1해도 c참조 하는 목록은 변경되지 않습니다.

복사의 개념은 정수 및 문자열과 같은 변경 불가능한 객체와 관련이 없습니다. 이러한 객체를 수정할 수 없으므로 서로 다른 위치의 메모리에 동일한 값의 사본 두 개를 가질 필요가 없습니다. 따라서 정수와 문자열 및 복사 개념이 적용되지 않는 다른 객체는 단순히 재 지정됩니다. 이것은 왜 당신의 예제와 함께입니다 ab동일한 IDS의 결과.

c1=copy.deepcopy(c)"딥 카피"이지만이 예에서는 얕은 카피와 동일하게 작동합니다. 딥 카피는 얕은 카피가 객체 자체의 새로운 카피를 만들지 만 그 객체 내부의 모든 참조 는 스스로 복사되지 않는다는 점에서 얕은 카피와 다릅니다 . 귀하의 예에서, 당신의 목록에는 그 안에 정수가 있고 (불변), 앞에서 논의했듯이 그것들을 복사 할 필요가 없습니다. 따라서 딥 카피의 "딥"부분은 적용되지 않습니다. 그러나 이보다 복잡한 목록을 고려하십시오.

e = [[1, 2],[4, 5, 6],[7, 8, 9]]

이것은 다른 목록을 포함하는 목록입니다 (2 차원 배열로도 설명 할 수 있음).

에서 "shallow copy"를 실행하여에 e복사 e1하면 목록의 id가 변경되지만 목록의 각 사본에는 동일한 세 개의 목록 (정수가 포함 된 목록)에 대한 참조가 포함됩니다. 즉, 당신이해야 e[0].append(3)한다면 e그렇게 될 것입니다 [[1, 2, 3],[4, 5, 6],[7, 8, 9]]. 그러나 e1또한 될 것 [[1, 2, 3],[4, 5, 6],[7, 8, 9]]입니다. 이후에했던 다른 한편, 만약 e.append([10, 11, 12]), e될 것이다 [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12]]. 그러나 e1여전히 그렇습니다 [[1, 2, 3],[4, 5, 6],[7, 8, 9]]. 외부 목록은 처음에 각각 3 개의 내부 목록에 대한 3 개의 참조를 포함하는 별도의 객체이기 때문입니다. 내부 목록을 수정하면 한 사본 또는 다른 사본을 통해 볼 때 변경 사항을 볼 수 있습니다. 그러나 위와 같이 외부 목록 중 하나를 수정하면e원본 세 목록에 대한 세 개의 참조와 새 목록에 대한 하나의 참조가 포함되어 있습니다. 그리고 e1여전히 원래 세 개의 참조 만 포함합니다.

'심층 복사'는 외부 목록을 복제 할뿐만 아니라 목록 내부로 이동하여 내부 목록을 복제하여 결과 객체 두 개에 동일한 참조가 포함되지 않도록 (변형 가능한 객체에 관한 한) . 내부 목록에 추가 목록 (또는 사전과 같은 다른 개체)이 있으면 그 목록도 복제됩니다. 이것이 '딥 카피'의 '딥'부분입니다.


2

파이썬에서 list, tuples, dict 등과 같은 객체를 일반적으로 '='기호로 다른 객체에 할당하면 python은 참조로 copy를 만듭니다 . 즉, 다음과 같은 목록이 있다고 가정 해 봅시다.

list1 = [ [ 'a' , 'b' , 'c' ] , [ 'd' , 'e' , 'f' ]  ]

우리는이 목록에 다음과 같이 다른 목록을 할당합니다.

list2 = list1

파이썬 터미널에 list2를 인쇄하면 다음과 같이됩니다.

list2 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f ']  ]

list1과 list2는 모두 동일한 메모리 위치를 가리키고 있습니다. 어느 하나를 변경하면 두 객체 모두에서 변경 사항이 표시됩니다. 즉, 두 객체 모두 동일한 메모리 위치를 가리 킵니다. list1을 다음과 같이 변경하면 :

list1[0][0] = 'x’
list1.append( [ 'g'] )

list1과 list2는 다음과 같습니다.

list1 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g'] ]
list2 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g’ ] ]

이제 얕은 복사를 통해 두 객체가 얕은 복사를 통해 복사 될 때 두 부모 객체의 자식 객체는 동일한 메모리 위치를 참조하지만 복사 된 객체의 새로운 변경 사항은 서로 독립적입니다. 작은 예제로 이것을 이해합시다. 이 작은 코드 스 니펫이 있다고 가정 해보십시오.

import copy

list1 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f ']  ]      # assigning a list
list2 = copy.copy(list1)       # shallow copy is done using copy function of copy module

list1.append ( [ 'g', 'h', 'i'] )   # appending another list to list1

print list1
list1 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g', 'h', 'i'] ]
list2 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f '] ]

list2는 영향을받지 않지만 다음과 같이 자식 객체를 변경하면 :

list1[0][0] = 'x’

list1과 list2는 모두 변경됩니다.

list1 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g', 'h', 'i'] ] 
list2 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] ]

이제 딥 카피 는 서로 완전히 고립 된 객체를 만드는 데 도움이됩니다. Deep Copy를 통해 두 객체를 복사하면 부모와 자식 모두 다른 메모리 위치를 가리 킵니다. 예 :

import copy

list1 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f ']  ]         # assigning a list
list2 = deepcopy.copy(list1)       # deep copy is done using deepcopy function of copy module

list1.append ( [ 'g', 'h', 'i'] )   # appending another list to list1

print list1
list1 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g', 'h', 'i'] ]
list2 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f '] ]

list2는 영향을받지 않지만 다음과 같이 자식 객체를 변경하면 :

list1[0][0] = 'x’

그러면 모든 자식 객체와 부모 객체가 다른 메모리 위치를 가리 키기 때문에 list2는 영향을받지 않습니다.

list1 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g', 'h', 'i'] ] 
list2 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f  ' ] ]

도움이 되길 바랍니다.


0

아래 코드는 할당, 복사 방법을 사용한 얕은 복사, (슬라이스) [:]를 사용한 얕은 복사 및 심도의 차이를 보여줍니다. 아래 예제는 차이점을보다 분명하게 보여줌으로써 중첩 된 목록을 사용합니다.

from copy import deepcopy

########"List assignment (does not create a copy) ############
l1 = [1,2,3, [4,5,6], [7,8,9]]
l1_assigned = l1

print(l1)
print(l1_assigned)

print(id(l1), id(l1_assigned))
print(id(l1[3]), id(l1_assigned[3]))
print(id(l1[3][0]), id(l1_assigned[3][0]))

l1[3][0] = 100
l1.pop(4)
l1.remove(1)


print(l1)
print(l1_assigned)
print("###################################")

########"List copy using copy method (shallow copy)############

l2 = [1,2,3, [4,5,6], [7,8,9]]
l2_copy = l2.copy()

print(l2)
print(l2_copy)

print(id(l2), id(l2_copy))
print(id(l2[3]), id(l2_copy[3]))
print(id(l2[3][0]), id(l2_copy[3][0]))
l2[3][0] = 100
l2.pop(4)
l2.remove(1)


print(l2)
print(l2_copy)

print("###################################")

########"List copy using slice (shallow copy)############

l3 = [1,2,3, [4,5,6], [7,8,9]]
l3_slice = l3[:]

print(l3)
print(l3_slice)

print(id(l3), id(l3_slice))
print(id(l3[3]), id(l3_slice[3]))
print(id(l3[3][0]), id(l3_slice[3][0]))

l3[3][0] = 100
l3.pop(4)
l3.remove(1)


print(l3)
print(l3_slice)

print("###################################")

########"List copy using deepcopy ############

l4 = [1,2,3, [4,5,6], [7,8,9]]
l4_deep = deepcopy(l4)

print(l4)
print(l4_deep)

print(id(l4), id(l4_deep))
print(id(l4[3]), id(l4_deep[3]))
print(id(l4[3][0]), id(l4_deep[3][0]))

l4[3][0] = 100
l4.pop(4)
l4.remove(1)

print(l4)
print(l4_deep)
print("##########################")
print(l4[2], id(l4[2]))
print(l4_deep[3], id(l4_deep[3]))

print(l4[2][0], id(l4[2][0]))
print(l4_deep[3][0], id(l4_deep[3][0]))

0

GIST는 다음과 같습니다. "정상 할당"을 사용하는 얕은 목록 (하위 목록, 단일 요소 만)을 처리하면 얕은 목록을 만든 다음 "정상 할당"을 사용하여이 목록의 복사본을 만들면 "부작용"이 발생합니다. . 이 "부작용"은 작성된 사본 목록의 요소를 변경하면 원래 목록의 동일한 요소가 자동으로 변경되기 때문에 발생합니다. 그 때는 copy복사 요소를 변경할 때 원래 목록 요소를 변경하지 않으므로, 유용합니다.

반면에 copy목록이 포함 된 목록 (sub_lists)이있을 때 "부작용"도 있습니다 deepcopy. 예를 들어 중첩 된 목록이있는 큰 목록 (sub_lists)을 작성하고이 큰 목록 (원본 목록)의 사본을 작성하는 경우가 있습니다. 복사 목록의 sub_list를 수정하면 큰 목록의 sub_list가 자동으로 수정 될 때 "부작용"이 발생합니다. 때로는 (일부 프로젝트에서) 큰 목록 (원본 목록)을 수정하지 않고 그대로 유지하려는 경우 원하는 요소 (sub_lists)의 사본을 만드는 것입니다. 이를 위해 귀하의 솔루션은 deepcopy이 "부작용"을 처리하고 원본 내용을 수정하지 않고 사본을 만드는 것을 사용 하는 것입니다.

다른 동작 copydeep copy작업은 복합 객체 (예 : 목록과 같은 다른 객체를 포함하는 객체)에만 해당됩니다.

이 간단한 코드 예제에서 설명 된 차이점은 다음과 같습니다.

먼저

copy원본 목록과이 목록의 복사본을 만들어 (얕은) 동작을 확인 하십시오.

import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)

이제 몇 가지 print테스트를 수행하고 원본 목록이 복사 목록과 비교하여 어떻게 작동하는지 봅시다 .

original_list와 copy_list의 주소가 다릅니다

print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328

original_list 및 copy_list의 요소는 동일한 주소를 갖습니다.

print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440

original_list와 copy_list의 sub_elements는 동일한 주소를 갖습니다.

print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x1faef08 0x1faef08

original_list 요소를 수정해도 copy_list 요소는 수정되지 않습니다

original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]

copy_list 요소를 수정해도 original_list 요소는 수정되지 않습니다

copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]

original_list sub_elements 수정 자동 copy_list sub_elements 수정

original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 7]

copy_list sub_elements 수정 자동으로 original_list sub_elements 수정

copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 7]

둘째

원래 목록과이 목록의 사본을 작성하여 deepcopy수행 한 것과 동일한 작업을 수행하여 동작을 확인하십시오 copy.

import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)

이제 몇 가지 print테스트를 수행하고 원본 목록이 복사 목록과 비교하여 어떻게 작동하는지 봅시다 .

import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.deepcopy(original_list)

original_list와 copy_list의 주소가 다릅니다

print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328

original_list 및 copy_list의 요소는 동일한 주소를 갖습니다.

print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440

original_list와 copy_list의 sub_elements의 주소가 다릅니다

print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x24eef08 0x24f3300

original_list 요소를 수정해도 copy_list 요소는 수정되지 않습니다

original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]

copy_list 요소를 수정해도 original_list 요소는 수정되지 않습니다

copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]

original_list sub_elements를 수정해도 copy_list sub_elements는 수정되지 않습니다

original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]

copy_list sub_elements를 수정해도 original_list sub_elements는 수정되지 않습니다

copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'd'], 7]

0

위에서 언급했는지 여부는 확실하지 않지만 .copy ()가 원래 객체에 대한 참조를 생성한다는 것을 이해하는 것은 매우 중요합니다. 복사 된 객체를 변경하면 원래 객체가 변경됩니다. .deepcopy ()는 새 객체를 만들고 원본 객체를 새 객체로 실제로 복사합니다. 새로운 심도있는 객체를 변경해도 원본 객체에는 영향을 미치지 않습니다.

예, .deepcopy ()는 원본 객체를 재귀 적으로 복사하지만 .copy ()는 원본 객체의 첫 번째 수준 데이터에 대한 참조 객체를 만듭니다.

따라서 .copy ()와 .deepcopy ()의 복사 / 참조 차이는 중요합니다.


0

딥 카피는 중첩 구조와 관련이 있습니다. 목록 목록이있는 경우 Deepcopy는 중첩 목록도 복사하므로 재귀 복사본입니다. 복사 만하면 새로운 외부 목록이 있지만 내부 목록은 참조입니다. 과제는 복사되지 않습니다. 예를 들어

import copy
spam = [[0, 1, 2, 3], 4, 5]
cheese = copy.copy(spam)
cheese.append(3)
cheese[0].append(3)
print(spam)
print(cheese)

산출

[[0, 1, 2, 3, 3], 4, 5] [[0, 1, 2, 3, 3], 4, 5, 3] 복사 방법 외부 목록의 내용을 새 목록으로 복사하지만 내부 목록은 목록의 내부 목록을 변경하면 두 목록에 모두 영향을 미칩니다.

그러나 Deep copy를 사용하면 내부 목록에 대한 새 인스턴스도 생성됩니다.

import copy
spam = [[0, 1, 2, 3], 4, 5]
cheese = copy.deepcopy(spam)
cheese.append(3)
cheese[0].append(3)
print(spam)
print(cheese)

산출

[0, 1, 2, 3] [[0, 1, 2, 3, 3], 4, 5, 3]


-1
>>lst=[1,2,3,4,5]

>>a=lst

>>b=lst[:]

>>> b
[1, 2, 3, 4, 5]

>>> a
[1, 2, 3, 4, 5]

>>> lst is b
False

>>> lst is a
True

>>> id(lst)
46263192

>>> id(a)
46263192 ------>  See here id of a and id of lst is same so its called deep copy and even boolean answer is true

>>> id(b)
46263512 ------>  See here id of b and id of lst is not same so its called shallow copy and even boolean answer is false although output looks same.

a의 사본이 아닙니다 lst!
Georgy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.