2013-05-13 46 views
5

Khi tôi xác định một danh sách theo một cách "chung chung":dereferencing danh sách bên trong danh sách bằng Python

>>>a=[[]]*3 
>>>a 
[[],[],[]] 

và sau đó cố gắng thêm chỉ tới phần tử thứ hai của danh sách bên ngoài:

>>>a[1].append([0,1]) 
>>>a 
[[[0,1]], [[0,1]], [[0,1]]] 

nó gắn vào tất cả các phần tử của danh sách bên ngoài như có thể thấy ở trên, có thể do thực tế là các phần tử là tham chiếu đến cùng một danh sách và không phải danh sách khác nhau (tại sao nó hoạt động theo cách đó?). Làm thế nào tôi có thể thực sự tạo ra một danh sách trong cùng một cách "chung chung", như vậy mà các danh sách bên trong sẽ là danh sách khác nhau và không chỉ tham khảo. Cảm ơn.

Trả lời

10

Bạn đúng, tất cả đều là tham chiếu đến một danh sách.

[[] for _ in range(3)] 

là cách phổ biến để tạo danh sách các danh sách trống độc lập. Bạn có thể sử dụng xrange trên Python 2.x, nhưng nó sẽ không tạo sự khác biệt nếu độ dài thực sự nhỏ như trong ví dụ của bạn.

Không chắc làm thế nào để giải thích lý do cho điều này (lý do là nó được thực hiện theo cách này), nhưng bạn có thể thấy rằng hành vi này là tài liệu (ít nhất là trong đi qua) here:

Operation  Result        Notes 
s * n, n * s n shallow copies of s concatenated (2) 

Từ "nông" ở đây có nghĩa là chính xác rằng: các phần tử được sao chép bằng tham chiếu. "Lưu ý 2" tại trang được liên kết cũng trả lời câu hỏi của bạn.

+1

Thực hiện bản sao nông là một lựa chọn thiết kế tốt. Làm một bản sao sâu sẽ phức tạp và tốn kém hơn nhiều. Ngoài ra nó sẽ là một cách dễ dàng để phá vỡ singletons: '[True] * n' và đột nhiên có' n' trường hợp khác nhau của 'True' (hoặc bất kỳ người dùng định nghĩa singleton), mà bạn rõ ràng là không muốn. – Bakuriu

+0

Cảm ơn. Bạn đã đề cập đến tôi có thể sử dụng "phạm vi" nếu chiều dài nhỏ? Trong dự án thực sự của tôi, chiều dài có thể lớn tới 10000. Tôi vẫn có thể sử dụng "dải ô"? Tôi nghĩ rằng nó sẽ vẫn làm việc cho hơn số lượng, phải không? – jazzblue

+0

@Gregory nó chắc chắn sẽ, nhưng một danh sách 10000 số sẽ được tạo ra và ngay lập tức bị xóa trong quá trình này. Điều đó có lẽ sẽ không ăn nhiều bộ nhớ, nhưng có thể sẽ chậm hơn một chút so với 'xrange'. Bạn có thể thời gian cả hai và xem. –

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