python list - 목록을 복제하거나 복사하는 방법은 무엇입니까?




deep copy (16)

다른 모든 제공자는 위대한 응답을주었습니다.이 방법은 단일 차원 (평준화) 목록을 가지고있을 때 작동하지만, 지금까지 언급 한 방법 중 copy.deepcopy() 만 목록을 복제 / 복사하고 그 목록을 가리 키지 않습니다 다차원, 중첩 된 목록 (목록 목록)으로 작업 할 때 중첩 된 list 개체. 이 그의 답변에서 언급 , deepcopy 대한보다 빠른 대안을 증명할 수있는 내장 기능을 사용하여 문제에 조금 더 접근 할 수 있습니다.

new_list = old_list[:] , copy.copy(old_list)' 와 Py3k old_list.copy() 는 단일 레벨 목록에서 작동하지만 old_listnew_list 중첩 된 list 객체를 가리키고 하나는 list 개체의 다른 개체는 다른 개체에서 영속적입니다.

편집 : 새 정보가 밝혀졌습니다.

Avalon 과 PM 2Ring이 eval() 사용하여 지적한 것처럼 나쁜 생각 일뿐만 아니라 copy.deepcopy() 보다 훨씬 느립니다.

즉, 다차원 목록의 경우 유일한 옵션은 copy.deepcopy() 입니다. 그렇게 말하면, 적당한 크기의 다차원 배열에서 성능을 사용하려고 할 때 성능이 남쪽으로가는만큼 실제로 옵션이 아닙니다. 42x42 어레이를 사용하여 timeit 을 시도했는데, 전례가없는 것이거나 심지어 생물 정보학 응용 프로그램에 큰 영향을 미치지 않았습니다. 응답을 기다리고 포스팅을 편집하기 시작했습니다.

유일한 옵션은 여러 목록을 초기화하고 독립적으로 작업하는 것입니다. 누구든지 다차원 목록 복사를 처리하는 방법에 대해 다른 제안 사항이 있으면 감사하겠습니다.

다른 사람들이 말했듯이, 다차원 목록을 위해 copy 모듈과 copy.deepcopy 사용하여 중요한 성능 문제 있을 수 있습니다 . deepcopy 를 사용하지 않고 다차원리스트를 복사하는 다른 방법을 찾으려고 노력했다. (나는 신용을 받기 위해 전체 알고리즘을 실행하는데 5 초 밖에 걸리지 않는 코스의 문제를 해결하기 위해 노력했다.) 나는 길을 찾았다. 내장 함수를 사용하여 서로 중첩되거나 중첩 된 list 객체를 가리 키지 않고 중첩리스트의 복사본을 만듭니다. 할당에서 eval()repr() 을 사용하여 이전 목록에 대한 링크를 만들지 않고 이전 목록의 복사본을 새 목록으로 만들었습니다. 그것은 다음과 같은 형식을 취합니다 :

new_list = eval(repr(old_list))

기본적으로 old_list 를 문자열로 표현한 다음 문자열이 나타내는 객체 인 것처럼 문자열을 평가합니다. 이렇게하면 원본 list 개체에 대한 링크가 만들어지지 않습니다. 새 list 개체가 만들어지고 각 변수는 자체 독립 개체를 가리 킵니다. 다음은 2 차원 중첩 목록을 사용하는 예입니다.

old_list = [[0 for j in range(y)] for i in range(x)] # initialize (x,y) nested list

# assign a copy of old_list to new list without them pointing to the same list object
new_list = eval(repr(old_list)) 

# make a change to new_list 
for j in range(y):
    for i in range(x):
    new_list[i][j] += 1

그런 다음 각 목록의 내용 (예 : 4 x 3 목록)을 확인하면 Python이 반환합니다

>>> new_list

[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]

>>> old_list

[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

이것은 아마도 정식 또는 구문 론적으로 올바른 방법이 아니지만 제대로 작동하는 것 같습니다. 나는 성능을 테스트하지는 않았지만, eval()rep()deepcopy 보다 실행하는 오버 헤드가 적을 것이라고 추측 할 것이다.

파이썬에서리스트를 복제하거나 복사하는 옵션은 무엇입니까?

new_list = my_list 를 사용하면 my_list 변경 될 때마다 new_list 수정됩니다.
왜 이런거야?


이미 적절한 사본을 만드는 방법을 알려주는 많은 답변이 있지만 그 중 누구도 원본 '사본'이 실패한 이유를 말하지 않습니다.

파이썬은 변수에 값을 저장하지 않습니다. 이름을 오브젝트에 바인드합니다. 원래 할당은 my_list 에 의해 참조 된 객체를 가져 와서 new_list 에도 바인딩했습니다. 어떤 이름을 사용하든 관계없이 하나의 목록 만 있으므로 my_list 로 참조 할 때 변경된 내용은 new_list 로 참조 할 때 그대로 유지됩니다. 이 질문에 대한 다른 대답은 new_list 에 바인딩 할 새 객체를 만드는 여러 가지 방법을 제공합니다.

목록의 각 요소는 이름처럼 작동합니다. 각 요소는 비 독점적으로 개체에 바인딩됩니다. 얕은 복사본은 요소가 이전과 같은 객체에 바인딩되는 새 목록을 만듭니다.

new_list = list(my_list)  # or my_list[:], but I prefer this syntax
# is simply a shorter way of:
new_list = [element for element in my_list]

목록 복사를 한 단계 더 진행하려면 목록에서 참조하는 각 개체를 복사하고 해당 요소 복사본을 새 목록에 바인딩하십시오.

import copy  
# each element must have __copy__ defined for this...
new_list = [copy.copy(element) for element in my_list]

목록의 각 요소는 다른 요소를 참조 할 수 있기 때문에 목록의 요소에 바인딩되어 있기 때문에 아직 자세한 내용은 아닙니다. 목록의 모든 요소를 ​​반복적으로 복사 한 다음 각 요소에서 참조하는 서로 다른 개체 등을 복사합니다. 전체 복사본을 수행합니다.

import copy
# each element must have __deepcopy__ defined for this...
new_list = copy.deepcopy(my_list)

복사하는 경우에 대한 자세한 내용은 설명서 를 참조하십시오.


파이썬 3.6.0 타이밍

다음은 파이썬 3.6.0을 사용한 타이밍 결과입니다. 이 시간들은 절대적이지 않고 서로에 상대적이라는 것을 명심하십시오.

필자는 얕은 복사본만을 사용하고, list.copy() (파이썬 3 슬라이스에 상응하는 )와리 스트 풀기 ( *new_list, = list )와 같이 list.copy() 에서는 불가능했던 몇 가지 새로운 메소드를 추가했다.

METHOD                  TIME TAKEN
b = a[:]                6.468942025996512   #Python2 winner
b = a.copy()            6.986593422974693   #Python3 "slice equivalent"
b = []; b.extend(a)     7.309216841997113
b = a[0:len(a)]         10.916740721993847
*b, = a                 11.046738261007704
b = list(a)             11.761539687984623
b = [i for i in a]      24.66165203397395
b = copy.copy(a)        30.853400873980718
b = []
for item in a:
  b.append(item)        48.19176080400939

파이썬 3의 list.copy() 접근법의 가독성을 고려할 때, 오래된 승자가 여전히 정상에 오르는 것을 볼 수는 있지만 엄청난 양은 아닙니다.

이러한 메서드는리스트 이외의 입력에 대해서는 동일한 결과를 출력하지 않습니다 . 그것들은 모두 슬라이스 가능한 객체에 대해 작동하고, 반복 가능한 객체에 대해서는 약간만 작동하지만, 어떤 Python 객체에 대해서만 copy.copy() 만 작동합니다.

이해 관계자를위한 테스트 코드는 다음과 같습니다 ( 여기에서 템플릿 참조 ).

import timeit

COUNT = 50000000
print("Array duplicating. Tests run", COUNT, "times")
setup = 'a = [0,1,2,3,4,5,6,7,8,9]; import copy'

print("b = list(a)\t\t", timeit.timeit(stmt='b = list(a)', setup=setup, number=COUNT))
print("b = copy.copy(a)\t\t", timeit.timeit(stmt='b = copy.copy(a)', setup=setup, number=COUNT))
print("b = a.copy()\t\t", timeit.timeit(stmt='b = a.copy()', setup=setup, number=COUNT))
print("b = a[:]\t\t", timeit.timeit(stmt='b = a[:]', setup=setup, number=COUNT))
print("b = a[0:len(a)]\t", timeit.timeit(stmt='b = a[0:len(a)]', setup=setup, number=COUNT))
print("*b, = a\t", timeit.timeit(stmt='*b, = a', setup=setup, number=COUNT))
print("b = []; b.extend(a)\t", timeit.timeit(stmt='b = []; b.extend(a)', setup=setup, number=COUNT))
print("b = []\nfor item in a: b.append(item)\t", timeit.timeit(stmt='b = []\nfor item in a:  b.append(item)', setup=setup, number=COUNT))
print("b = [i for i in a]\t", timeit.timeit(stmt='b = [i for i in a]', setup=setup, number=COUNT))

파이썬에서리스트를 복제하거나 복사하는 옵션은 무엇입니까?

Python 3에서는 다음과 같이 얕은 복사본을 만들 수 있습니다.

a_copy = a_list.copy()

파이썬 2와 3에서는 원본의 전체 슬라이스로 얕은 복사본을 얻을 수 있습니다 :

a_copy = a_list[:]

설명

목록을 복사하는 의미 론적 방법은 두 가지가 있습니다. 얕은 복사본은 동일한 개체의 새 목록을 만들고 딥 복사본은 새로운 동일한 개체가 포함 된 새 목록을 만듭니다.

얕은 목록 복사

얕은 복사본은 목록의 개체에 대한 참조의 컨테이너 인 목록 자체 만 복사합니다. 포함 된 오브젝트가 변경 가능하고 하나가 변경된 경우, 변경 사항은 두리스트 모두에 반영됩니다.

파이썬 2와 파이썬 3에서 다른 방법이 있습니다. 파이썬 2 웨이는 파이썬 3에서도 작동합니다.

파이썬 2

파이썬 2에서리스트의 얕은 사본을 만드는 관용적 인 방법은 원본의 완전한 슬라이스를 사용하는 것입니다 :

a_copy = a_list[:]

목록 생성자를 통해 목록을 전달하여 동일한 작업을 수행 할 수도 있습니다.

a_copy = list(a_list)

그러나 생성자를 사용하는 것은 덜 효율적입니다.

>>> timeit
>>> l = range(20)
>>> min(timeit.repeat(lambda: l[:]))
0.30504298210144043
>>> min(timeit.repeat(lambda: list(l)))
0.40698814392089844

파이썬 3

Python 3에서 list는 list.copy 메소드를 얻는다.

a_copy = a_list.copy()

파이썬 3.5에서 :

>>> import timeit
>>> l = list(range(20))
>>> min(timeit.repeat(lambda: l[:]))
0.38448613602668047
>>> min(timeit.repeat(lambda: list(l)))
0.6309100328944623
>>> min(timeit.repeat(lambda: l.copy()))
0.38122922903858125

다른 포인터를 만드는 것은 복사본을 만들지 않습니다.

new_list = my_list를 사용하면 my_list가 변경 될 때마다 new_list가 수정됩니다. 왜 이런거야?

my_list 는 메모리의 실제 목록을 가리키는 이름입니다. 복사본을 만들지 않은 new_list = my_list 라고 말하면 메모리의 원래 목록을 가리키는 다른 이름을 추가하기 만하면됩니다. 목록을 복사 할 때 비슷한 문제가 발생할 수 있습니다.

>>> l = [[], [], []]
>>> l_copy = l[:]
>>> l_copy
[[], [], []]
>>> l_copy[0].append('foo')
>>> l_copy
[['foo'], [], []]
>>> l
[['foo'], [], []]

목록은 내용에 대한 포인터의 배열이므로 얕은 사본은 포인터 만 복사하기 때문에 두 개의 다른 목록이 있지만 내용은 동일합니다. 내용을 복사하려면 깊은 사본이 필요합니다.

딥 카피

파이썬 2 또는 3에서 목록의 전체 복사본 을 만들려면 copy 모듈에서 deepcopy 를 사용하십시오 .

import copy
a_deep_copy = copy.deepcopy(a_list)

이것이 새로운 하위 목록을 만드는 방법을 보여주기 위해 :

>>> import copy
>>> l
[['foo'], [], []]
>>> l_deep_copy = copy.deepcopy(l)
>>> l_deep_copy[0].pop()
'foo'
>>> l_deep_copy
[[], [], []]
>>> l
[['foo'], [], []]

그래서 우리는 깊은 복사 목록이 원본과 완전히 다른 목록이라는 것을 알 수 있습니다. 당신은 자신의 기능을 굴릴 수는 있지만 그렇게하지는 마십시오. 표준 라이브러리의 deepcopy 기능을 사용하지 않으면 얻을 수없는 버그를 만들 수 있습니다.

eval 사용하지 마십시오.

이것을 딥 카피하는 방법으로 사용하는 것을 볼 수는 있지만 그렇게하지는 마십시오 :

problematic_deep_copy = eval(repr(a_list))
  1. 위험합니다. 특히 신뢰하지 않는 출처에서 무언가를 평가하는 경우 더욱 그렇습니다.
  2. 복사하는 하위 요소에 동등한 요소를 재생산 할 수있는 표현이 없으면 신뢰할 수 없습니다.
  3. 그것은 또한 덜 performant입니다.

64 비트 Python 2.7 :

>>> import timeit
>>> import copy
>>> l = range(10)
>>> min(timeit.repeat(lambda: copy.deepcopy(l)))
27.55826997756958
>>> min(timeit.repeat(lambda: eval(repr(l))))
29.04534101486206

64 비트 Python 3.5 :

>>> import timeit
>>> import copy
>>> l = list(range(10))
>>> min(timeit.repeat(lambda: copy.deepcopy(l)))
16.84255409205798
>>> min(timeit.repeat(lambda: eval(repr(l))))
34.813894678023644

이것은 아직 언급되지 않았기 때문에 놀랍습니다. 그래서 완전성을 위해서 ...

"splat operator": * 사용하여 목록 압축을 수행 할 수 있습니다. * 는 목록의 요소를 복사합니다.

old_list = [1, 2, 3]

new_list = [*old_list]

new_list.append(4)
old_list == [1, 2, 3]
new_list == [1, 2, 3, 4]

이 방법의 명백한 단점은 Python 3.5 이상에서만 사용 가능하다는 것입니다.

현명한 타이밍이지만 다른 일반적인 방법보다 성능이 좋은 것으로 보입니다.

x = [random.random() for _ in range(1000)]

%timeit a = list(x)
%timeit a = x.copy()
%timeit a = x[:]

%timeit a = [*x]

#: 2.47 µs ± 38.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
#: 2.47 µs ± 54.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
#: 2.39 µs ± 58.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

#: 2.22 µs ± 43.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

thing[:] 사용 thing[:]

>>> a = [1,2]
>>> b = a[:]
>>> a += [3]
>>> a
[1, 2, 3]
>>> b
[1, 2]
>>> 

python 버전과 독립적 인 매우 간단한 접근법은 이미 주어진 답변에서 빠졌습니다. 대부분의 경우 (적어도 필자는) 사용할 수 있습니다.

new_list = my_list * 1       #Solution 1 when you are not using nested lists

그러나 my_list에 다른 컨테이너 (예 : 중첩 목록)가 포함되어 있으면 위의 응답에서 제안한 다른 라이브러리와 같이 deepcopy를 사용해야합니다. 예 :

import copy
new_list = copy.deepcopy(my_list)   #Solution 2 when you are using nested lists

. 보너스 : 요소를 복사하지 않으려면 (얕은 사본이라고도 함) :

new_list = my_list[:]

솔루션 # 1과 솔루션 # 2의 차이점을 이해해 봅시다.

>>> a = range(5)
>>> b = a*1
>>> a,b
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])
>>> a[2] = 55 
>>> a,b
([0, 1, 55, 3, 4], [0, 1, 2, 3, 4])

당신이 볼 수 있듯이 중첩 목록을 사용하지 않을 때 Solution # 1은 완벽하게 작동했습니다. 중첩 목록에 솔루션 # 1을 적용 할 때 어떤 일이 발생하는지 확인해 봅시다.

>>> from copy import deepcopy
>>> a = [range(i,i+4) for i in range(3)]
>>> a
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> b = a*1
>>> c = deepcopy(a)
>>> for i in (a, b, c): print i   
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> a[2].append('99')
>>> for i in (a, b, c): print i   
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5, 99]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5, 99]]   #Solution#1 didn't work in nested list
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]       #Solution #2 - DeepCopy worked in nested list

이것이 여전히 실제인지는 모르지만 사전에는 동일한 동작이 적용됩니다. 이 예를보십시오.

a = {'par' : [1,21,3], 'sar' : [5,6,8]}
b = a
c = a.copy()
a['har'] = [1,2,3]

a
Out[14]: {'har': [1, 2, 3], 'par': [1, 21, 3], 'sar': [5, 6, 8]}

b
Out[15]: {'har': [1, 2, 3], 'par': [1, 21, 3], 'sar': [5, 6, 8]}

c
Out[16]: {'par': [1, 21, 3], 'sar': [5, 6, 8]}

처음부터 시작해서 좀 더 깊이 탐구 해 봅시다.

그래서 두 목록이 있다고 가정 해보십시오.

list_1=['01','98']
list_2=[['01','98']]

그리고 두 목록을 모두 복사해야합니다. 이제 첫 번째 목록에서 시작합니다.

먼저 일반적인 복사 방법으로 시도해 보겠습니다.

copy=list_1

이제 list_1을 복사 한 것으로 생각하면 잘못 될 수 있습니다. 확인해 봅시다.

The id() function shows us that both variables point to the same list object, i.e. they share this object.
print(id(copy))
print(id(list_1))

산출:

4329485320
4329485320

놀랐지? 이제 살펴 보겠습니다.

파이썬은 변수에 아무것도 저장하지 않는다는 것을 알기 때문에, 변수는 단지 객체를 참조하고 객체는 값을 저장합니다. 여기에 객체가 있지만 두 개의 다른 변수 이름으로 동일한 객체에 대한 두 개의 참조를 만들었습니다. 따라서 두 변수 모두 동일한 객체를 가리키고 있습니다.

그래서 copy=list_1 할 때 실제로 무엇을하는지 :

여기 이미지 list_1과 copy는 두 개의 변수 이름이지만 객체는 두 변수 모두에 대해 동일 list

따라서 복사 된 목록을 수정하려고하면 목록이 하나뿐이기 때문에 원래 목록도 수정됩니다. 복사 된 목록이나 원본 목록에서 상관없이 목록을 수정하게됩니다.

copy[0]="modify"

print(copy)
print(list_1)

산출:

['modify', '98']
['modify', '98']

그래서 원래 목록을 수정했습니다 :

그러면 그 해결책은 무엇입니까?

해결책 :

이제 목록을 복사하는 두 번째 비유 방법으로 이동해 보겠습니다.

copy_1=list_1[:]

이제이 방법은 첫 번째 문제에서 우리가 직면 한 것을 수정 해 봅니다.

print(id(copy_1))
print(id(list_1))

4338792136
4338791432

그래서 우리는 두리스트가 다른 id를 갖는 것을 볼 수 있습니다. 두 변수가 서로 다른 객체를 가리키고 있다는 것을 의미합니다. 그래서 실제로 여기에서 진행되는 것은 :

이제 목록을 수정하여 이전 문제가 계속 발생하는지 봅시다.

copy_1[0]="modify"

print(list_1)
print(copy_1)

산출:

['01', '98']
['modify', '98']

따라서 원본 목록을 수정하지 않고 복사 된 목록 만 수정 했으므로 확인해 볼 수 있습니다.

이제 우리는 끝난 것 같아? 우리가 두 번째 중첩 목록을 복사해야하므로 잠깐 기다려보십시오.

copy_2=list_2[:]

그래서 list_2는 list_2의 복사본 인 다른 객체를 참조해야합니다.

print(id((list_2)),id(copy_2))

우리는 결과를 얻는다 :

4330403592 4330403528

이제 우리는 두리스트가 서로 다른 객체를 가리키고 있다고 가정 할 수 있습니다. 이제 그것을 수정하려고합니다. 그리고 그것이 우리가 원하는 것을 제공하는지 봅시다.

그래서 우리가 시도 할 때 :

copy_2[0][1]="modify"

print(list_2,copy_2)

그것은 우리에게 산출물을 준다 :

[['01', 'modify']] [['01', 'modify']]

자, 이것은 우리가 파이썬 방법을 사용하면서 혼란스럽지 않고 여전히 똑같은 문제에 직면하고 있습니다.

그것을 이해하자 :

그래서 우리가 할 때 :

copy_2=list_2[:]

우리는 실제로 중첩 된 목록이 아닌 외부 목록 만 복사하므로 중첩 된 목록은 두 목록 모두에 대해 동일한 개체입니다. 확인해 봅시다.

print(id(copy_2[0]))
print(id(list_2[0]))

산출:

4329485832
4329485832

그래서 실제로 copy_2=list_2[:] 할 때 이것은 일어납니다 :

리스트의 사본을 생성하지만 중첩 된리스트 복사가 아닌 중첩 된리스트 만 복사합니다. 중첩 된리스트는 두 변수 모두에서 동일합니다. 따라서 중첩 된리스트를 수정하려고하면 중첩 된리스트 객체가 모두 동일하기 때문에 원래의리스트도 수정합니다 중첩 목록.

그래서 해결책은 무엇입니까?

해결책은 deep copy

from copy import deepcopy
deep=deepcopy(list_2)

이제 확인해 보겠습니다.

print(id((list_2)),id(deep))

산출:

4322146056 4322148040

두 ID가 다르기 때문에 이제 중첩 목록 ID를 확인해 보겠습니다.

print(id(deep[0]))
print(id(list_2[0]))

산출:

4322145992
4322145800

보시다시피 두 ID는 다르기 때문에 두 중첩 된 목록이 다른 객체를 가리키고 있다고 가정 할 수 있습니다.

따라서 deep=deepcopy(list_2) 할 때 실제로 일어나는 일 :

따라서 중첩 목록은 서로 다른 객체를 가리키고 있으며 중첩 목록의 사본을 별도로 가지고 있습니다.

이제 중첩 목록을 수정하고 이전 문제를 해결했는지 확인해 봅시다.

그래서 우리가한다면 :

deep[0][1]="modify"
print(list_2,deep)

산출:

[['01', '98']] [['01', 'modify']]

따라서 원래의 중첩 목록을 수정하지 못했지만 복사 된 목록 만 수정했습니다.

만약 당신이 내 세부 답변을 좋아한다면, 당신이 의심의 여지 가이 답변을 realted있다, upvoting하여 알려 주시기 바랍니다 :)


이것을하기위한 파이썬의 관용구는 newList = oldList[:]


사용자 정의 클래스를 정의하고 속성을 유지하려는 경우 Python 3과 같이 대안 대신 copy.copy() 또는 copy.deepcopy() 를 사용해야하는 경우가 있습니다.

import copy

class MyList(list):
    pass

lst = MyList([1,2,3])

lst.name = 'custom list'

d = {
'original': lst,
'slicecopy' : lst[:],
'lstcopy' : lst.copy(),
'copycopy': copy.copy(lst),
'deepcopy': copy.deepcopy(lst)
}


for k,v in d.items():
    print('lst: {}'.format(k), end=', ')
    try:
        name = v.name
    except AttributeError:
        name = 'NA'
    print('name: {}'.format(name))

출력 :

lst: original, name: custom list
lst: slicecopy, name: NA
lst: lstcopy, name: NA
lst: copycopy, name: custom list
lst: deepcopy, name: custom list

new_list = my_list[:]

new_list = my_list 이것을 이해하십시오. my_list가 X 위치의 힙 메모리에 있다고 가정합니다. 즉, my_list가 X를 가리키고 있습니다. 이제 new_list = my_list 를 지정하면 new_list가 X를 가리키게됩니다. 이것을 얕은 복사라고합니다.

이제 new_list = my_list[:] 를 할당하면 new_list = my_list[:] 각 객체를 new_list에 복사하는 것입니다. 이를 딥 복사라고합니다.

이렇게 할 수있는 다른 방법은 다음과 같습니다.

  • new_list = list(old_list)
  • import copy new_list = copy.deepcopy(old_list)

new_list = list(old_list)


당신은 list () 함수에서 bulit를 사용할 수 있습니다 :

newlist=list(oldlist)

나는이 코드가 당신을 도울 것이라고 생각한다.


변수와 값 을 가진 다른 언어와 달리 Python은 이름과 객체를 가지고 있습니다.

이 진술 :

a = [1,2,3]

목록 (객체)에 이름 a 를 부여하는 것을 의미하며,

b = a

동일한 객체 a 새로운 이름 인 b 를 부여하기 때문에, b 를 사용하여 무언가를 할 때마다 객체가 변경되므로 b 변경됩니다.

실제 복사본을 만드는 유일한 방법은 이미 다른 답변과 마찬가지로 새 개체만드는 것 입니다.

이에 대한 자세한 내용은 here 참조 here .


Python 3에서는 collections.ChainMap 을 사용하여 여러 dicts 또는 다른 매핑을 함께 그룹화하여 업데이트 가능한 단일보기를 만들 수 있습니다.

>>> from collections import ChainMap
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = ChainMap({}, y, x)
>>> for k, v in z.items():
        print(k, '-->', v)

a --> 1
b --> 10
c --> 11




python list copy clone