Sao chép hoặc tham khảo bài tập python
Đầu tiên mình mô tả một chút về quản lý và tối ưu bộ nhớ trong Python. Sau khi đặt nền tảng, tôi giải thích sự khác biệt giữa câu lệnh gán, bản sao nông và bản sao sâu. Sau đó tôi tóm tắt sự khác biệt trong một bảng Show Nếu bạn thích xem video hơn là đọc một bài viết, bạn có thể tìm thấy video bổ sung tại đây Quản lý bộ nhớ trong Pythonint, float, list, dict, class instance,… chúng đều là đối tượng trong Python. Trong quá trình triển khai CPython, hàm tích hợp sẵn >>> L1 = [1, 2, 3]>>> id(L1)3 trả về địa chỉ bộ nhớ của một đối tượng — >>> L1 = [1, 2, 3]>>> id(L1) Nếu chúng ta tạo một biến mới >>> L1 = [1, 2, 3]>>> id(L1)4 tham chiếu đến một đối tượng có cùng giá trị với >>> L1 = [1, 2, 3]>>> id(L1)5, thì >>> L1 = [1, 2, 3]>>> id(L1)4 sẽ có một địa chỉ bộ nhớ mới — >>> L2 = [1, 2, 3]>>> id(L2) Mỗi khi một đối tượng mới được tạo, nó sẽ có một địa chỉ bộ nhớ mới. Ngoại trừ khi nó là -
Hãy xem một ví dụ với một đối tượng số nguyên. Cả >>> L1 = [1, 2, 3]>>> id(L1)7 và >>> L1 = [1, 2, 3]>>> id(L1)8 đều đề cập đến cùng một giá trị 10. Trong khi >>> L1 = [1, 2, 3]>>> id(L1)5 và >>> L1 = [1, 2, 3]>>> id(L1)4 trong ví dụ trước có hai địa chỉ bộ nhớ khác nhau, thì >>> L1 = [1, 2, 3]>>> id(L1)7 và >>> L1 = [1, 2, 3]>>> id(L1)8 chia sẻ cùng một địa chỉ bộ nhớ — >>> L1 = [1, 2, 3]>>> id(L1)2 Đó là bởi vì, trong ba trường hợp ngoại lệ đó, Python tối ưu hóa bộ nhớ bằng cách để biến thứ hai tham chiếu đến cùng một đối tượng trong bộ nhớ, — một số người gọi nó là “đối tượng được chia sẻ” Hãy ghi nhớ khái niệm về đối tượng được chia sẻ vì chúng ta sẽ cần đến nó sau này khi chúng ta tạo một bản sao sâu của một đối tượng Chuyển nhượng biếnNó nói trong tài liệu Python rằng “Các câu lệnh gán trong Python không sao chép các đối tượng, chúng tạo ra các liên kết giữa một mục tiêu và một đối tượng. ” Điều đó có nghĩa là khi chúng ta tạo một biến bằng cách gán, biến mới đề cập đến cùng một đối tượng như biến ban đầu — >>> L1 = [1, 2, 3]>>> id(L1)3 Bởi vì biến mới >>> L2 = [1, 2, 3]>>> id(L2)3 và biến ban đầu >>> L2 = [1, 2, 3]>>> id(L2)4 chia sẻ cùng một đối tượng (i. e. cùng một danh sách), chúng cũng chứa các phần tử giống nhau — >>> L1 = [1, 2, 3]>>> id(L1)6 Như minh họa trong hình bên dưới, >>> L2 = [1, 2, 3]>>> id(L2)4 và >>> L2 = [1, 2, 3]>>> id(L2)3 chia sẻ cùng một >>> L2 = [1, 2, 3]>>> id(L2)7, i. e. , chúng tham chiếu đến cùng một đối tượng trong bộ nhớ. Và chúng cũng chứa các yếu tố giống nhau Bản sao nôngKhi chúng ta tạo một biến bằng bản sao nông, biến mới đề cập đến một đối tượng mới — >>> L1 = [1, 2, 3]>>> id(L1)0 Mặc dù >>> L2 = [1, 2, 3]>>> id(L2)4 và >>> L2 = [1, 2, 3]>>> id(L2)9 đề cập đến hai đối tượng khác nhau (i. e. hai danh sách có địa chỉ bộ nhớ khác nhau), các phần tử trong hai danh sách đề cập đến cùng một đối tượng — >>> L1 = [1, 2, 3]>>> id(L1)3 Hình bên dưới minh họa cách các phần tử trong >>> L2 = [1, 2, 3]>>> id(L2)4 đề cập đến các đối tượng giống như các phần tử trong >>> L2 = [1, 2, 3]>>> id(L2)9 Sao chép sâuTương tự như sao chép nông, khi chúng ta tạo một biến bằng cách sao chép sâu, biến mới tham chiếu đến một đối tượng mới — >>> L1 = [1, 2, 3]>>> id(L1)6 Như được mô tả trong tài liệu Python —
Vì vậy, khác với bản sao nông, các phần tử trong hai danh sách hiện đề cập đến các đối tượng khác nhau - >>> L1 = [1, 2, 3]>>> id(L1)7 Nhưng tại sao >>> L1 = [1, 2, 3]>>> id(L1)22 và >>> L1 = [1, 2, 3]>>> id(L1)23 chia sẻ cùng một đối tượng (tôi. e. có cùng địa chỉ bộ nhớ)? Hình dưới đây cho thấy >>> L2 = [1, 2, 3]>>> id(L2)4 và >>> L1 = [1, 2, 3]>>> id(L1)25 đề cập đến hai danh sách khác nhau trong bộ nhớ và các phần tử trong >>> L2 = [1, 2, 3]>>> id(L2)4 đề cập đến các đối tượng khác với các phần tử trong >>> L1 = [1, 2, 3]>>> id(L1)25 ngoại trừ các phần tử số nguyên do tối ưu hóa bộ nhớ Bản tóm tắtNếu có một điểm rút ra từ bài viết này, thì đó phải là bảng dưới đây. Phép gán biến không sao chép các đối tượng, vì vậy >>> L2 = [1, 2, 3]>>> id(L2)4 và >>> L2 = [1, 2, 3]>>> id(L2)3 có cùng địa chỉ bộ nhớ và chứa các phần tử giống nhau. Bản sao nông tạo một đối tượng mới cho >>> L2 = [1, 2, 3]>>> id(L2)9, nhưng các phần tử trong >>> L2 = [1, 2, 3]>>> id(L2)9 vẫn tham chiếu đến các đối tượng giống như các phần tử trong >>> L2 = [1, 2, 3]>>> id(L2)4. Bản sao sâu cũng tạo đối tượng mới cho >>> L1 = [1, 2, 3]>>> id(L1)25 và các phần tử trong >>> L1 = [1, 2, 3]>>> id(L1)25 đề cập đến các đối tượng khác với các phần tử đó trong >>> L2 = [1, 2, 3]>>> id(L2)4 với ba loại ngoại lệ Bài tập Python có phải là bản sao hoặc tài liệu tham khảo không?Trong Python, Các câu lệnh gán không sao chép các đối tượng , chúng tạo ra các ràng buộc giữa mục tiêu và đối tượng. Khi chúng ta sử dụng toán tử =, Nó chỉ tạo một biến mới chia sẻ tham chiếu của đối tượng ban đầu.
Bài tập có tạo một bản sao trong Python không?Các câu lệnh gán trong Python không sao chép các đối tượng , chúng tạo ra các ràng buộc giữa mục tiêu và đối tượng. Đối với các bộ sưu tập có thể thay đổi hoặc chứa các mục có thể thay đổi, đôi khi cần có một bản sao để một người có thể thay đổi một bản sao mà không cần thay đổi bản kia.
Bài tập Python có phải là bản sao sâu không?Sử dụng phép gán = nếu bạn muốn những thay đổi mới ảnh hưởng đến danh sách ban đầu. Sử dụng bản sao sâu nếu bạn không muốn những thay đổi mới ảnh hưởng đến danh sách ban đầu . Nhớ lại. bản sao sâu đảm bảo rằng đối tượng mới được sao chép không được tham chiếu đến đối tượng ban đầu theo bất kỳ cách nào.
Python có sao chép danh sách khi được giao không?Tóm lại, toán tử gán (=) tạo một tham chiếu mới tới một đối tượng trong bộ nhớ. Nó không sao chép bất cứ thứ gì . Điều này áp dụng cho danh sách cũng như bất kỳ đối tượng nào khác trong Python. |