2013-06-13 71 views
9

Chỉ khi tôi nghĩ rằng tôi đã hiểu thế nào danh sách Python làm việc ...Sao chép danh sách python

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

Cho đến nay, như vậy tốt. Tôi đang khởi tạo b với nội dung của a, sao cho b trỏ đến một đối tượng khác. Kết quả là, những thay đổi trong b không ảnh hưởng đến a.

Bây giờ hãy nhìn vào ví dụ khác này:

>>> a = [[1,2,3],[4,5,6],[7,8,9]] 
>>> b = a[:][:] 
>>> b 
[[1,2,3],[4,5,6],[7,8,9]] 
>>> b[1][1] = 100 
>>> b 
[[1,2,3],[4,100,6],[7,8,9]] 
>>> a 
[[1,2,3],[4,100,6],[7,8,9]] 

Tại sao sự thay đổi trong b ảnh hưởng một thời gian này? Điều gì khác với ví dụ trước?

+1

Lưu ý rằng việc sử dụng '[:]' để sao chép là một chút khó hiểu - thường tôi thấy nó đẹp hơn nhiều khi sử dụng 'list()' hoặc 'copy.copy()', tùy thuộc vào ngữ cảnh. (Tất nhiên, như được chỉ ra trong câu trả lời, 'copy.deepcopy()' có thể là những gì bạn muốn ở đây). –

Trả lời

11

Thao tác cắt x[:] tạo bản sao nông. Điều đó có nghĩa, danh sách bên ngoài là khác nhau, nhưng có chứa các yếu tố chính xác giống nhau. giả a = [[1]]:

b = a[:] # is the same as: 
b = [x for x in a] 

>>> a[0] is b[0] 
True 

Các cắt đôi ([:][:]) là không làm gì nhiều hơn thế - một lần nữa:

b = a[:][:] # is the same as: 
b = [y for y in [x for x in a]] 

>>> a[0] is b[0] 
True 

Một bản sao cạn của một bản sao cạn là, tốt, một bản sao cạn.

Vì vậy, b vẫn là bản sao nông a - các danh sách này là các đối tượng khác nhau, nhưng chúng chứa các phần tử giống nhau. Sau đó, bạn thay đổi danh sách bên trong trong b, nhưng nó là cùng một danh sách trong a.

Bản sao nông 2 cấp có thể được thực hiện với b=[x[:] for x in a]. Nó mở rộng cùng một cách cho bản sao n-level.

Nhân tiện, thuật ngữ "bản sao nông" có ý nghĩa tương tự đối với bất kỳ lớp hoặc vùng chứa nào.

Nếu bạn muốn bản sao thật sâu, bạn nên cân nhắc sử dụng deep copy.

+1

Một 'bản sao nông'! Tôi không biết khái niệm đó. Có lẽ bạn có thể chỉnh sửa một chút câu trả lời để giải thích thêm một chút (chỉ một vài từ). –

+0

+1 để có giải thích tốt cùng với giải pháp – Sid

+0

@MarcosGonzalez giờ đây có tốt hơn không? – Elazar

4

Việc đóng băng [:] tạo bản sao nông. nhưng đối tượng bên trong vẫn không được sao chép vì vậy nếu họ có thể thay đổi và Bạn sẽ được sửa đổi với họ rằng họ sẽ được sửa đổi;) và trong cả hai danh sách Bạn sẽ thấy điều này

danh sách sử dụng hiểu

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

hoặc copy.deepcopy()

import copy 
b = copy.deepcopy(a) 
+0

Cảm ơn bạn đã gợi ý! –

1

Hãy thử điều này:

In [38]: import copy 

In [39]: a = [[1,2,3],[4,5,6],[7,8,9]] 

In [40]: b=copy.deepcopy(a) 

In [41]: b[1][1] = 100 

In [42]: a 
Out[42]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

In [43]: b 
Out[43]: [[1, 2, 3], [4, 100, 6], [7, 8, 9]] 

Read more @http://docs.python.org/2/library/copy.html

+0

Cảm ơn bạn đã gợi ý. –

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