2010-04-29 16 views
36

thể trùng lặp:
Unexpected feature in a Python list of listsdanh sách 2D có behavor lạ khi cố gắng sửa đổi một giá trị duy nhất

Vì vậy, Tôi tương đối mới để Python và tôi đang gặp khó khăn làm việc với Lists 2D.

Dưới đây là mã của tôi:

data = [[None]*5]*5 
data[0][0] = 'Cell A1' 
print data 

và đây là sản phẩm (định dạng để có thể đọc):

[['Cell A1', None, None, None, None], 
['Cell A1', None, None, None, None], 
['Cell A1', None, None, None, None], 
['Cell A1', None, None, None, None], 
['Cell A1', None, None, None, None]] 

Tại sao mỗi hàng được gán giá trị?

+4

Oh cậu bé, là tôi bị mắc kẹt trên vấn đề này cùng trở lại trong ngày .. :) – ktdrv

Trả lời

45

Điều này làm cho một danh sách với lăm tài liệu tham khảo vào danh sách cùng:

data = [[None]*5]*5 

Sử dụng một cái gì đó như thế này thay vì đó tạo lăm danh sách riêng biệt:

>>> data = [[None]*5 for _ in range(5)] 

Bây giờ nó làm những gì bạn mong đợi:

>>> data[0][0] = 'Cell A1' 
>>> print data 
[['Cell A1', None, None, None, None], 
[None, None, None, None, None], 
[None, None, None, None, None], 
[None, None, None, None, None], 
[None, None, None, None, None]] 
2

Trong python mọi biến là ob ject, và một tham chiếu. Đầu tiên bạn tạo một mảng gồm 5 Nones, và sau đó bạn xây dựng một mảng với 5 lần cùng một đối tượng.

8

Khi python library reference for sequence types, trong đó bao gồm các danh sách, nói

Cũng lưu ý rằng các bản sao là nông cạn; cấu trúc lồng nhau không được sao chép. Điều này thường ám ảnh các lập trình viên Python mới; xem xét:

>>> lists = [[]] * 3 
>>> lists 
    [[], [], []] 
>>> lists[0].append(3) 
>>> lists 
    [[3], [3], [3]] 

gì đã xảy ra là [[]] là danh sách một phần tử có chứa một danh sách rỗng, vì vậy tất cả ba yếu tố của [[]] * 3 là (con trỏ tới) này danh sách trống duy nhất. Sửa đổi bất kỳ phần tử nào trong danh sách sửa đổi danh sách đơn này.

Bạn có thể tạo một danh sách các danh sách khác nhau theo cách này:

>>> lists = [[] for i in range(3)] 
>>> lists[0].append(3) 
>>> lists[1].append(5) 
>>> lists[2].append(7) 
>>> lists 
    [[3], [5], [7]]