2008-10-08 75 views

Trả lời

86

Nếu bạn muốn có một bản sao cạn (yếu tố không được sao chép) sử dụng:

lst2=lst1[:] 

Nếu bạn muốn tạo một bản sao sâu sau đó sử dụng các module sao chép:

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

Bạn có ý nghĩa gì bởi các yếu tố không được sao chép? – sheats

+4

Nếu các phần tử là các đối tượng có thể thay đổi được chúng được truyền qua tham chiếu, bạn phải sử dụng bản in sâu để thực sự sao chép chúng. –

+2

Nó sẽ chỉ sao chép tài liệu tham khảo được tổ chức theo danh sách. Nếu một phần tử trong danh sách giữ một tham chiếu đến một đối tượng khác, thì nó sẽ không được sao chép. 9 lần trong số 10 bạn chỉ cần bản sao nông. –

18

Tôi thường sử dụng:

lst2 = lst1 * 1 

Nếu lst1 nó chứa các thùng chứa khác (như các danh sách khác), bạn nên sử dụng bản in sâu từ bản sao lib như được hiển thị bởi Mark.


UPDATE: Giải thích 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]) 

Như bạn có thể thấy chỉ có một thay đổi ... Tôi sẽ cố gắng bây giờ với một danh sách liệt kê

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

Không phải như vậy có thể đọc được, hãy để tôi in nó bằng chữ cái cho:

>>> 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ạn thấy không? Nó cũng nối vào b [1], vì vậy b [1] và [1] là cùng một đối tượng. Bây giờ thử nó với 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()' sẽ không hoạt động trong trường hợp cuối cùng, bạn cần 'deepcopy()' bất cứ khi nào bạn có tham chiếu bên trong đối tượng. –

+1

Tôi nghĩ rằng mẹo sử dụng 'lst1 * 1' của bạn thật sự rất hay ... nhưng, thật đáng buồn, hồ sơ thô sơ gợi ý rằng nó ít nhất gấp hai lần so với' lst1 [:] ', nhanh hơn một chút so với' copy (last1) '. – Andrew

2

Bạn cũng có thể làm điều này:

import copy 
list2 = copy.copy(list1) 

này nên làm điều tương tự như bản sao cạn Mark Roddy của.

12

Bạn cũng có thể làm:

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

Kết quả là bản sao nông hay sâu? – minty

+8

Không, sử dụng danh sách() chắc chắn là bản sao nông. Hãy dùng thử. –

+2

Có sự khác biệt về tốc độ không? Có thể cho rằng khi bạn làm '[:]', thư viện đủ thông minh để biết rằng một bản sao đang được tạo ra và do đó nó có khả năng có thể gọi một số mã C gốc để làm như vậy. Với 'list (iterable)' có biết/quan tâm rằng iterable đã được vật chất hóa và do đó có thể được sao chép hiệu quả? –

6

tôi muốn làm:

lst2 = list(lst1) 

Các lợi thế hơn lst1 [:] là các thành ngữ cùng làm việc cho dicts:

dct2 = dict(dct1) 
+0

Có thực sự là một cuộc thảo luận khá dài về bản sao từ điển so với bản sao danh sách trên danh sách gửi thư của Python 3K: http://mail.python.org/pipermail/python-3000/2008-February/thread.html#12052 –

+0

bit thông tin ở đây là cho từ điển, bạn có thể làm d = d.copy() –

0

Về hiệu suất, có một số chi phí để gọi list() so với cắt. Vì vậy, đối với các danh sách ngắn, lst2 = lst1[:] nhanh hơn gấp hai lần là lst2 = list(lst1).

Trong hầu hết các trường hợp, điều này có lẽ lớn hơn bởi thực tế là list() dễ đọc hơn, nhưng trong các vòng lặp chặt chẽ, đây có thể là một tối ưu hóa có giá trị.

3

danh sách ngắn, [:] là tốt nhất:

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 

Đối với danh sách lớn hơn, chúng ta đều như nhau:

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 

Đối với danh sách rất lớn (Tôi đã thử 50mm), chúng vẫn giống nhau.

+0

Tôi sẽ không bận tâm nếu tôi phải làm một bản sao ở giữa 100 dòng mã. Chỉ khi nó là một phần cốt lõi của ứng dụng và bản sao danh sách là thường xuyên, tôi có thể bận tâm. – Saurabh

Các vấn đề liên quan