2016-03-10 20 views
5

Tôi có câu hỏi với phương pháp sao chép từ điển ví dụ cho phép nói rằng tôi cóPython từ điển bản sao phương pháp

>> d = {'pears': 200, 'apples': 400, 'oranges': 500, 'bananas': 300} 

>> copy_dict = d.copy() 

Bây giờ nếu tôi kiểm tra id của cả d và copy_dict, cả hai đều khác nhau

>> id(d) 
o/p = 140634603873176 

>> id(copy_dict) 
o/p = 140634603821328 

nhưng nếu tôi kiểm tra id của các đối tượng trong từ điển có cùng ý nghĩa id (d ['lê']) = id (copy_dict ['pears'])

>> id(d['pears']) 
o/p = 140634603971648 
>> id (copy_dict['pears']) 
o/p = 140634603971648 

Tất cả các đối tượng trong dict mới là tham chiếu đến cùng một đối tượng như dict gốc.

Bây giờ nếu tôi thay đổi giá trị của khóa 'lê' trong d, không có thay đổi trong cùng một khóa trong copy_dict và khi tôi kiểm tra id bây giờ, id (d ['pears'])! = Id (copy_dict [ 'lê'])

>> d['pears'] = 700 
>> print copy_dict['pears'] 
o/p = 200 

câu hỏi của tôi là nếu các đối tượng trong dict mới được tham chiếu đến các đối tượng tương tự như các dict gốc tại sao là giá trị của dict mới không thay đổi khi giá trị trong bản gốc từ điển đã thay đổi và làm thế nào Python ngay lập tức thay đổi id của ngay khi nó thấy giá trị thay đổi?

Bạn có thể vui lòng cho tôi mô tả đầy đủ về sự khác biệt giữa bản sao sâu và nông không?

+0

Bản sao có thể có của [Hiểu dict.copy() - nông hoặc sâu?] (Http://stackoverflow.com/questions/3975376/understanding-dict-copy-shallow-or-deep) – Backtrack

Trả lời

2

bằng cách thay đổi giá trị, bạn đang thay đổi nội dung trỏ đến. Thay đổi giá trị trong từ điển gốc sẽ không thay đổi những gì chìa khóa trong bản sao đang trỏ đến.

Một bản sao cạn xây dựng một đối tượng hợp chất mới và sau đó (đến phạm vi có thể) chèn tài liệu tham khảo vào nó để các đối tượng được tìm thấy trong bản gốc.

Bản sao sâu tạo đối tượng kết hợp mới và sau đó, đệ quy, chèn bản sao vào đối tượng được tìm thấy trong số gốc.

Khi bạn sao chép thứ gì đó, nó sao chép giá trị ban đầu của đối tượng đang sao chép, nhưng nó tạo đối tượng mới. Nó không phản chiếu đối tượng gốc.

+0

Nhưng khi chúng tôi sao chép nội dung nào đó các đối tượng trong dict mới là tham chiếu đến các đối tượng giống như ý nghĩa dict gốc, cả hai địa chỉ đều giống nhau, đó là bí danh, do đó, những thay đổi được thực hiện cho một cũng nên thay đổi dict mới phải không? vì cả hai đều trỏ đến cùng một địa chỉ. – sans0909

+0

không, bằng cách sử dụng copy(), bạn đang tạo một đối tượng mới. Bạn sẽ sử dụng toán tử gán cho những gì bạn đang cố gắng làm: 'copy_dict = d' sau đó khi bạn cập nhật' d' nó cũng sẽ cập nhật 'copy_dict' vì chúng là cùng một đối tượng. – lciamp

+0

cảm ơn bạn @lciamp – sans0909

0

Lý do là bạn đã thực hiện thao tác gán thay thế giá trị, chứ không phải thao tác sửa đổi giá trị.

copy_dict = d.copy() 

gây ra một mới dict được tạo ra và các phím của nó/giá trị đã được khởi tạo từ d. Bạn đã lưu ý điểm quan trọng - đây là những đối tượng riêng biệt với các id khác nhau chỉ xảy ra để tham chiếu cùng khóa và giá trị.

d['pears'] = 700 

loại bỏ các tham chiếu đến 200 từ d['pears'] và thêm một tham chiếu đến 700. Việc tái chỉ định này được thực hiện trên đối tượng d vì vậy nó sẽ không bị các dicts khác nhìn thấy một cách tự nhiên mà chỉ đơn giản được khởi tạo bởi cùng khóa và giá trị.

Ngược lại, lẽ bạn đã chỉ đơn giản là giao dict gốc cho một biến thứ hai

copy_dict = d 

Ở đây, vì cả hai dcopy_dict tham khảo cùng dict, tái bổ nhiệm vào dict đó sẽ được nhìn thấy bởi cả hai biến bởi vì họ tham chiếu cùng một đối tượng.

+0

Cảm ơn bạn rất nhiều, rõ ràng là bây giờ :-) – sans0909

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