2008-10-08 8 views
47

목록을 복사하는 가장 좋은 방법은 무엇입니까? 나는 다음 중 어떤 것이 더 나은지 알고있다. 아니면 다른 방법이 있습니까? 당신이 (요소는 복사되지 않습니다) shallow 복사를 원하는 경우목록을 복사하는 가장 좋은 방법은 무엇입니까?

lst = ['one', 2, 3] 

lst1 = list(lst) 

lst2 = lst[:] 

import copy 
lst3 = copy.copy(lst) 

답변

86

사용 :

lst2=lst1[:] 

당신이 깊은 복사 한 후, 복사 모듈을 사용하게하려면 :

import copy 
lst2=copy.deepcopy(lst1) 
+1

요소가 복사되지 않았다는 것은 무엇을 의미합니까? – sheats

+4

요소가 참조로 전달 된 가변 객체 인 경우 deepcopy를 사용하여 실제로 복사해야합니다. –

+2

목록에있는 참조 만 복사합니다. 목록의 요소가 다른 객체에 대한 참조를 보유하고 있으면 그 요소는 복사되지 않습니다. 10 번 중 9 번만 얕은 사본이 필요합니다. –

18

을 자주 사용합니다 :

lst2 = lst1 * 1 

lst1에 다른 컨테이너와 마찬가지로 (다른 목록과 마찬가지로) Mark에 표시된 것처럼 복사 본에서 deepcopy를 사용해야합니다.


UPDATE : deepcopy는

>>> 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]) 

당신은 단지 변경 볼 수 있습니다으로 ... 나는 목록

>>> 
>>> a = [range(i,i+3) for i in range(3)] 
>>> a 
[[0, 1, 2], [1, 2, 3], [2, 3, 4]] 
>>> b = a*1 
>>> a,b 
([[0, 1, 2], [1, 2, 3], [2, 3, 4]], [[0, 1, 2], [1, 2, 3], [2, 3, 4]]) 

그리 읽을의 목록을 지금 노력 할게요 설명하면서, 그것을 위해 인쇄 할게 :

>>> for i in (a,b): print i 
[[0, 1, 2], [1, 2, 3], [2, 3, 4]] 
[[0, 1, 2], [1, 2, 3], [2, 3, 4]] 
>>> a[1].append('appended') 
>>> for i in (a,b): print i 

[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]] 
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]] 

너 알지? 그것은 b [1]에도 덧붙여져 있으므로 b [1]과 a [1]은 똑같은 대상입니다. 지금 당신은이 작업을 수행 할 수 있습니다 deepcopy

>>> from copy import deepcopy 
>>> b = deepcopy(a) 
>>> a[0].append('again...') 
>>> for i in (a,b): print i 

[[0, 1, 2, 'again...'], [1, 2, 3, 'appended'], [2, 3, 4]] 
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]] 
+2

'copy()'가 마지막 경우에는 작동하지 않을 것입니다. 객체 내부에 참조가있을 때마다'deepcopy()'가 필요합니다. –

+1

'lst1 * 1 '을 사용하는 것이 정말 좋다고 생각했지만 ... 슬프게도, 대략적인 프로파일 링은'lst1 [:]'보다 적어도 두 배 느리다는 것을 보여줍니다. last1)'. – Andrew

2

으로 시도 :

import copy 
list2 = copy.copy(list1) 

마크 로디의 얕은 복사와 같은 일을해야한다.

12

또한 수행 할 수 있습니다

a = [1, 2, 3] 
b = list(a) 
+2

결과가 얕은 또는 깊은 복사본입니까? – minty

+8

아니요, list()를 사용하면 확실히 얕은 사본입니다. 그것을 밖으로 시도하십시오. –

+2

속도 차이가 있습니까? 아마 당신이'[:]'을 할 때, 라이브러리는 복사본이 만들어지고 있다는 것을 알기에 충분히 똑똑하기 때문에 잠재적으로 네이티브 C 코드를 호출 할 수 있습니다. 'list (iterable) '를 사용하면 iterable이 이미 구체화되어 있으므로 효율적으로 복사 할 수 있다는 것을 알고 있습니까? –

6

는 내가하고 싶은 :

lst2 = list(lst1) 

lst1의 이상 장점 [:] 같은 관용구가 dicts 작동한다는 것입니다 :

dct2 = dict(dct1) 
+0

파이썬 3K 메일 링리스트에서 사전 사본 대리스트 사본에 대한 꽤 긴 토론이있었습니다. http://mail.python.org/pipermail/python-3000/2008-February/thread.html#12052 –

+0

정보의 비트는 사전에 대해 d = d.copy()를 수행 할 수 있다는 것입니다. –

0

성능 측면에서 슬라이싱 대비 list()을 호출하는 데 약간의 오버 헤드가 있습니다. 따라서 짧은 목록의 경우 lst2 = lst1[:]lst2 = list(lst1)보다 약 두 배 빠릅니다.

대부분의 경우, 이것은 아마도 list()이 더 읽기 쉽지만 타이트한 루프에서는 이것이 가치있는 최적화가 될 수 있다는 사실보다 중요합니다.

3

짧은 목록, [:] : 그들은 모두 거의 같은 것, 더 큰 목록에 대한

In [1]: l = range(10) 

In [2]: %timeit list(l) 
1000000 loops, best of 3: 477 ns per loop 

In [3]: %timeit l[:] 
1000000 loops, best of 3: 236 ns per loop 

In [6]: %timeit copy(l) 
1000000 loops, best of 3: 1.43 us per loop 

: 최고입니다 매우 큰 목록 (내가 50MM 시도)에 대한

In [7]: l = range(50000) 

In [8]: %timeit list(l) 
1000 loops, best of 3: 261 us per loop 

In [9]: %timeit l[:] 
1000 loops, best of 3: 261 us per loop 

In [10]: %timeit copy(l) 
1000 loops, best of 3: 248 us per loop 

, 그들은 여전히 ​​동일합니다.

+0

100 줄의 코드 줄 사이에 하나의 복사본을 작성해야한다면 신경 쓰지 않을 것입니다. 응용 프로그램의 핵심 부분이고 목록 사본이 자주 나오는 경우에만 나는 귀찮을 수 있습니다. – Saurabh

관련 문제