programing

목록을 자세히 복사하려면 어떻게 해야 합니까?

randomtip 2022. 10. 12. 21:19
반응형

목록을 자세히 복사하려면 어떻게 해야 합니까?

끝나고E0_copy = list(E0),그런 것 같다.E0_copy의 깊은 복사입니다.E0부터id(E0)와 동등하지 않다id(E0_copy)그럼 수정하겠습니다.E0_copy루프가 되어 있는데, 왜?E0똑같지 않아요?

E0 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for k in range(3):
    E0_copy = list(E0)
    E0_copy[k][k] = 0
    #print(E0_copy)
print E0  # -> [[0, 2, 3], [4, 0, 6], [7, 8, 0]]

E0_copy깊이 있는 복사가 아닙니다.상세 복사는 다음 방법으로 작성하지 않습니다.list()(양쪽 모두)list(...)그리고.testList[:]얄팍한 카피).

목록을 자세히 복사하는 데 사용합니다.

deepcopy(x, memo=None, _nil=[])
    Deep copy operation on arbitrary Python objects.

다음의 스니펫을 참조해 주세요.

>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b   # b changes too -> Not a deepcopy.
[[1, 10, 3], [4, 5, 6]]

이제 를 참조해 주세요.deepcopy작동

>>> import copy
>>> b = copy.deepcopy(a)
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]
>>> a[0][1] = 9
>>> a
[[1, 9, 3], [4, 5, 6]]
>>> b    # b doesn't change -> Deep Copy
[[1, 10, 3], [4, 5, 6]]

설명하자면list(...)는 내부 객체의 복사본을 반복적으로 만들지 않습니다.가장 바깥쪽 목록만 복사하고 동일한 내부 목록을 참조합니다. 따라서 내부 목록을 변환하면 변경 내용이 원래 목록과 얕은 복사본 모두에 반영됩니다.얄팍한 복사가 내부 목록을 참조하는 것을 알 수 있습니다.id(a[0]) == id(b[0])어디에b = list(a).

Python에는 다음과 같은 모듈이 있습니다.copy다음 두 가지 유용한 기능이 있습니다.

import copy
copy.copy()
copy.deepcopy()

copy()얕은 복사 기능입니다.지정된 인수가 복합 데이터 구조(예: 목록)인 경우 Python은 동일한 유형의 다른 개체(이 경우 새 목록)를 생성하지만 이전 목록 내의 모든 개체에 대해 참조만 복사됩니다.다음과 같이 생각할 수 있습니다.

newList = [elem for elem in oldlist]

직감적으로 추측할 수 있습니다.deepcopy()같은 패러다임을 따르며 유일한 차이점은 각 elem에 대해 deepcopy를 재귀적으로 호출한다는 것입니다(mbguy의 답변과 같습니다).

하지만 이건 옳지 않아!

deepcopy()는 원래 복합 데이터의 그래픽 구조를 실제로 보존합니다.

a = [1,2]
b = [a,a] # there's only 1 object a
c = deepcopy(b)

# check the result
c[0] is a # False, a new object a_1 is created
c[0] is c[1] # True, c is [a_1, a_1] not [a_1, a_2]

이 부분이 까다로운 부분입니다.deepcopy()해시테이블(Python에서는 사전)은 각 오래된 오브젝트 ref를 각 새로운 오브젝트 ref에 매핑하기 위해 사용됩니다.이것에 의해 불필요한 중복을 방지하고, 따라서 복사된 복합 데이터의 구조를 유지합니다.

공식 문서

목록의 내용이 기본 데이터 유형인 경우 이해를 사용할 수 있습니다.

new_list = [i for i in old_list]

다음과 같은 다차원 목록에 대해 중첩할 수 있습니다.

new_grid = [[i for i in row] for row in grid]

@수크릿 칼라

No.1:list(),[:],copy.copy()모두 얄팍한 카피입니다.물체가 복합적인 경우에는 모두 적합하지 않습니다.를 사용해야 합니다.copy.deepcopy().

No.2:b = a직접적으로,a그리고.b같은 참조를 가지다, 변경a변화하고 있다b.

a를 b로 설정하다

만약 그렇다면a로.b직접적으로,a그리고.b점유율 1참조입니다.

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


>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = a
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]

섀도 카피

타고list()

list()그리고.[:]똑같다.첫번 째 층 변화를 제외하면, 모든 다른 계층들의 변화로 이관된다.

>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0] = 1
>>> a
[1, [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]


>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]

타고에 의해[:]

>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = a[:]
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0] = 1
>>> a
[1, [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]


>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = a[:]
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]

list() 및 [:]는 첫 번째 레이어를 제외한 다른 레이어를 변경합니다.

# =========== [:] ===========
>>> a = [[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b = a[:]
>>> a
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> a[0][2] = 4
>>> a
[[1, 2, 4], [4, 5, 6]]
>>> b
[[1, 2, 4], [4, 5, 6]]


>>> a = [[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b = a[:]
>>> a
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> a[0][2][0] = 999
>>> a
[[1, 2, [999, 6]], [4, 5, 6]]
>>> b
[[1, 2, [999, 6]], [4, 5, 6]]



# =========== list() ===========
>>> a = [[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> a[0][2] = 4
>>> a
[[1, 2, 4], [4, 5, 6]]
>>> b
[[1, 2, 4], [4, 5, 6]]


>>> a = [[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b = list(a)
>>> a
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> b
[[1, 2, [3.5, 6]], [4, 5, 6]]
>>> a[0][2][0] = 999
>>> a
[[1, 2, [999, 6]], [4, 5, 6]]
>>> b
[[1, 2, [999, 6]], [4, 5, 6]]

타고에 의해copy()

찾게 할 곧 알게 될 것이다copy()기능은기능은 와 동일합니다와 같다.list()그리고 그리고.[:]모두 얕은 카피입니다.

얕은 복사 및 깊은 복사에 대한 자세한 내용은 여기를 참조하십시오.

>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = copy.copy(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 10, 3], [4, 5, 6]]

타고에 의해deepcopy()

>>> import copy
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = copy.deepcopy(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0] = 1
>>> a
[1, [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]


>>> a = [[1, 2, 3], [4, 5, 6]]
>>> b = copy.deepcopy(a)
>>> a
[[1, 2, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 10
>>> a
[[1, 10, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]

목록 요소가 불변의 객체인 경우 이 오브젝트를 사용할 수 있으며, 그렇지 않은 경우 를 사용해야 합니다.deepcopy부터에서copy모듈.모듈.

또한 깊은 복사본을 또한 딥 카피를 위해 최단 방법을 사용할 수 있습니다에 짧은 길을 사용할 수 있다.list이것처럼.이것처럼.

a = [0,1,2,3,4,5,6,7,8,9,10]
b = a[:] #deep copying the list a and assigning it to b
print id(a)
20983280
print id(b)
12967208

a[2] = 20
print a
[0, 1, 20, 3, 4, 5, 6, 7, 8, 9,10]
print b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10]

다음은 2D 목록을 자세히 복사하는 방법의 예입니다.

  b = [x[:] for x in a]

모듈을 직접 Import할 수 없는 경우 자체 deepcopy 함수를 다음과 같이 정의할 수 있습니다.

def copyList(L):
if type(L[0]) != list:
    return [i for i in L]
else:
    return [copyList(L[i]) for i in range(len(L))]

그것은 쉽게 볼 수 있다 -

>>> x = [[1,2,3],[3,4]]
>>> z = copyList(x)
>>> x
[[1, 2, 3], [3, 4]]
>>> z
[[1, 2, 3], [3, 4]]
>>> id(x)
2095053718720
>>> id(z)
2095053718528
>>> id(x[0])
2095058990144
>>> id(z[0])
2095058992192
>>>

재귀적인 딥 카피 함수일 뿐입니다.

def deepcopy(A):
    rt = []
    for elem in A:
        if isinstance(elem,list):
            rt.append(deepcopy(elem))
        else:
            rt.append(elem)
    return rt

에서 설명한 바와 같이 이것은 ": Cfreak"에 .copy★★★★★★ 。

목록을 트리로 볼 때 python의 deep_copy는 가장 콤팩트하게 다음과 같이 쓸 수 있습니다.

def deep_copy(x):
    if not isinstance(x, list):
        return x
    else:
        return [deep_copy(elem) for elem in x]

기본적으로 깊이 우선적인 방법으로 목록을 재귀적으로 넘나드는 것입니다.

언급URL : https://stackoverflow.com/questions/17873384/how-to-deep-copy-a-list

반응형