Bản sao sâu của Python không hoạt động
Trong Python, bản sao nông là bản sao “sâu một cấp độ”. Đối tượng được sao chép chứa tham chiếu đến đối tượng con của đối tượng ban đầu Show Một bản sao sâu hoàn toàn độc lập với đối tượng ban đầu. Nó xây dựng một đối tượng bộ sưu tập mới bằng cách điền đệ quy nó với các bản sao của các đối tượng con sao chép hay khôngTrong Python, bạn có thể sử dụng bản sao toán tử print(id(numbers))2 của một đối tượng. Thật hấp dẫn khi nghĩ rằng điều này tạo ra một đối tượng mới, nhưng nó không. Thay vào đó, nó tạo một biến mới tham chiếu đến đối tượng ban đầu. Điều này có nghĩa là thay đổi một giá trị trong đối tượng được sao chép cũng sẽ thay đổi giá trị của đối tượng ban đầu Hãy sử dụng danh sách để chứng minh điều này numbers = [1, 2, 3] new_numbers = numbers new_numbers[0] = 100 print('numbers: ', numbers) print('new_numbers: ', new_numbers) đầu ra numbers: [100, 2, 3] Vì print(id(numbers))3 và print(id(numbers))4 hiện trỏ đến cùng một danh sách nên việc cập nhật danh sách này luôn cập nhật danh sách kia Để xác minh rằng cả hai đối tượng thực sự tham chiếu đến cùng một đối tượng, bạn cũng có thể sử dụng phương thức print(id(numbers))5 . Mỗi đối tượng Python có một ID duy nhất. Nếu kiểm tra ID của print(id(numbers))3 và print(id(numbers))4, bạn có thể thấy chúng hoàn toàn giống nhau print(id(numbers)) đầu ra 139804802851400 Đây là một minh họa hữu ích Cách sao chép bằng PythonHãy đi qua một ví dụ phổ biến. Bạn muốn sao chép một danh sách sao cho danh sách ban đầu không bị thay đổi khi cập nhật danh sách đã sao chép. Có hai cách để sao chép trong Python
Cả hai phương pháp này đều được triển khai trong mô-đun print(id(numbers))8. Để sử dụng những thứ này, bạn cần nhập mô-đun print(id(numbers))8 vào dự án của mình
Hãy tìm hiểu sâu hơn về các chi tiết Sao chép nông vs. Sao chép sâuBản sao nôngBản sao nông là nông vì nó chỉ sao chép đối tượng chứ không sao chép các đối tượng con của nó. Thay vào đó, các đối tượng con tham chiếu đến các đối tượng con của đối tượng ban đầu Điều này có thể được chứng minh bằng ví dụ sau numbers = [1, 2, 3] new_numbers = numbers new_numbers[0] = 100 print('numbers: ', numbers) print('new_numbers: ', new_numbers)4 Ở đây, bạn có 1398048028514002, là một danh sách gồm các số. Và bạn có một bản sao sơ sài có tên là 1398048028514003. Hãy kiểm tra những
numbers: [100, 2, 3]1 đầu ra numbers: [100, 2, 3]2 Có vẻ như 1398048028514003 là một bản sao hoàn toàn độc lập của 1398048028514002. Nhưng hãy tiến thêm một bước để thấy rằng không phải 2. Đây là nơi mà sự nông cạn trở nên rõ ràng. ID của các danh sách trong 1398048028514003 bằng với ID của các danh sách trong 1398048028514002 gốc numbers: [100, 2, 3]7 đầu ra numbers: [100, 2, 3]8 Độ nông có nghĩa là chỉ danh sách “bên ngoài” được sao chép. Nhưng danh sách bên trong vẫn đề cập đến danh sách của danh sách gốc. Do đó, việc thay đổi một số trong danh sách đã sao chép sẽ ảnh hưởng đến danh sách gốc numbers: [100, 2, 3]9 đầu ra numbers: [100, 2, 3]0 3. Danh sách "bên ngoài" của 1398048028514003 là bản sao "thực" của bản gốc 1398048028514002. Do đó, bạn có thể thêm các phần tử mới vào nó hoặc thậm chí thay thế các phần tử hiện có. Những thay đổi này sẽ không ảnh hưởng đến danh sách 1398048028514002 ban đầu Ví dụ: hãy thay thế danh sách đầu tiên trong 1398048028514003 bằng một chuỗi. Điều này sẽ không ảnh hưởng đến ____92 numbers: [100, 2, 3]1 đầu ra numbers: [100, 2, 3]2 Bản sao sâuMột bản sao sâu tạo ra một bản sao hoàn toàn độc lập của đối tượng ban đầu Việc này thật thẳng thắn. Nhưng để hoàn thiện, hãy lặp lại các thí nghiệm trên với một bản sao sâu numbers: [100, 2, 3]3 Ở đây, bạn có 1398048028514002, là một danh sách chứa danh sách các số. Và bạn có một bản sao sâu, 1398048028514003. Hãy kiểm tra những
numbers: [100, 2, 3]1 đầu ra numbers: [100, 2, 3]5 2. ID của các danh sách trong 1398048028514003 không bằng ID của các danh sách trong 1398048028514002 numbers: [100, 2, 3]7 đầu ra numbers: [100, 2, 3]7 Việc thay đổi một số trong 1398048028514003 không thay đổi giá trị đó trong 1398048028514002 ban đầu numbers: [100, 2, 3]9 đầu ra numbers: [100, 2, 3]9 3. _ 1398048028514003 là bản sao độc lập của 1398048028514002. Do đó, không có cách nào thay đổi được thực hiện trong 1398048028514003 sẽ hiển thị trong bản gốc 1398048028514002 numbers: [100, 2, 3]1 đầu ra print(id(numbers))1 Sự kết luậnHôm nay bạn đã học được sự khác biệt giữa bản sao nông và bản sao sâu trong Python là gì Bản sao nông là bản sao “sâu một cấp độ”. Nó xây dựng một đối tượng được sao chép. Nhưng các đối tượng con đề cập đến các đối tượng con của đối tượng ban đầu. Vì vậy, thoạt nghe có vẻ hơi “lạ” Danh sách Python có sao chép bản sao sâu không?Bản sao Python. copy() đã tạo một bản sao thực sự của danh sách gốc. Tuy nhiên, đó vẫn là một bản sao nông và các danh sách lồng nhau đề cập chính xác đến cùng một vị trí bộ nhớ. Nói cách khác, bản. copy() chỉ tạo các bản sao cấp cao nhất và không sao chép các đối tượng lồng nhau.
Danh sách () có tạo bản sao sâu không?Bạn không tạo một bản sao sâu bằng list() .
Bản sao () nông hay sâu?Trong Bản sao nông, một bản sao của đối tượng ban đầu được lưu trữ và cuối cùng chỉ có địa chỉ tham chiếu được sao chép. Trong Bản sao sâu, cả bản sao của đối tượng gốc và bản sao lặp lại đều được lưu trữ. 2.
. Sao chép sâu Bản sao sâu có làm chậm Python không?deepcopy() cực kỳ chậm . Lưu câu hỏi này. Hiển thị hoạt động trên bài đăng này. Tôi có một trạng thái trò chơi bằng Python với khoảng 1000 đối tượng (hệ hành tinh + sao + hành tinh) và tôi cần sao chép nó cũng như áp dụng một loạt các phép biến đổi cho nó khi được yêu cầu. |