Trong Python, bạn có thể tạo một bản sao nông và sâu bằng phương thức l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 của danh sách, từ điển, v.v. , hoặc các hàm l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 và l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 3 của mô-đun sao chép
- sao chép — Thao tác sao chép nông và sâu — Python 3. 9. 6 tài liệu
Bài viết này mô tả các nội dung sau
- Sao chép nông và sao chép sâu trong Python
- Gán cho một biến khác
- Bản sao nông. l1 = [0, 1, [2, 3]]
l2 = l1
print(l1 is l2)
# True
l1[1] = 100
l1[2][0] = 200
print(l1)
# [0, 100, [200, 3]]
print(l2)
# [0, 100, [200, 3]]
print(l1 is l2)
# True
1, l1 = [0, 1, [2, 3]]
l2 = l1
print(l1 is l2)
# True
l1[1] = 100
l1[2][0] = 200
print(l1)
# [0, 100, [200, 3]]
print(l2)
# [0, 100, [200, 3]]
print(l1 is l2)
# True
5, v.v.
- l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 phương pháp liệt kê, từ điển, v.v.
- Lát cắt
- l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 7, l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 8, v.v.
- l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 5
- Bản sao sâu. i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False 0
Sau đây là tóm tắt về sự khác biệt giữa việc gán cho một biến khác, bản sao nông và bản sao sâu
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 0
nguồn. copy_deepcopy. py
Liên kết được tài trợ
Sao chép nông và sao chép sâu trong Python
Tài liệu chính thức của Python mô tả bản sao nông và bản sao sâu như sau
Sự khác biệt giữa sao chép nông và sâu chỉ liên quan đến các đối tượng phức hợp (các đối tượng chứa các đối tượng khác, như danh sách hoặc thể hiện của lớp)
- Một bản sao nông xây dựng một đối tượng phức hợp mới và sau đó (trong phạm vi có thể) chèn vào đó các tham chiếu tới các đối tượng được tìm thấy trong bản gốc
- Một bản sao sâu xây dựng một đối tượng phức hợp mới và sau đó, theo cách đệ quy, chèn các bản sao của các đối tượng được tìm thấy trong bản gốc vào đó. sao chép — Thao tác sao chép nông và sâu — Python 3. 9. 6 tài liệu
Đối với các đối tượng trong các đối tượng có thể thay đổi, chẳng hạn như danh sách và từ điển (= các phần tử trong danh sách hoặc giá trị trong từ điển), bản sao nông chèn tham chiếu và bản sao sâu chèn bản sao. Trong trường hợp các tham chiếu, chúng là cùng một đối tượng, vì vậy nếu một trong số chúng bị thay đổi, thì đối tượng kia cũng bị thay đổi
Gán cho một biến khác
Đầu tiên, hãy xem điều gì xảy ra khi gán cho một biến
Khi một đối tượng có thể thay đổi như danh sách hoặc từ điển được gán cho nhiều biến, việc cập nhật một biến (= thay đổi, thêm hoặc xóa các phần tử, v.v. ) cũng sẽ cập nhật các biến khác
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True
nguồn. copy_deepcopy. py
Như bạn có thể thấy từ kết quả của i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False 1, hai biến tham chiếu đến cùng một đối tượng cả trước và sau khi giá trị được thay đổi
- 6. Biểu thức - So sánh danh tính — Python 3. 9. 6 tài liệu
Để tạo một bản sao thay vì một tham chiếu của cùng một đối tượng, hãy sử dụng phương thức l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 hoặc hàm i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False 0 được mô tả bên dưới
Ngược lại, trong trường hợp các đối tượng không thay đổi được như số i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False 4, i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False 5 và chuỗi i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False 6 thì không thể cập nhật giá trị của đối tượng. Khi được gán, hai biến là cùng một đối tượng, nhưng khi một biến được cập nhật giá trị mới, nó sẽ trở thành một đối tượng khác, còn biến kia giữ nguyên
i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False
nguồn. copy_deepcopy. py
Liên kết được tài trợ
Bản sao nông. l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1, l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 5, v.v.
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 phương pháp liệt kê, từ điển, v.v.
Phương thức l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 được cung cấp cho danh sách, từ điển, v.v. Phương pháp l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 tạo một bản sao nông
Như đã đề cập ở trên, một bản sao nông sẽ chèn một tham chiếu đến một đối tượng trong đối tượng gốc. Ví dụ: trong trường hợp bản sao nông của danh sách, bản thân danh sách là một đối tượng khác, nhưng các phần tử của nó là các tham chiếu đến cùng các đối tượng trong các phần tử của danh sách gốc
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 4
nguồn. copy_deepcopy. py
Do đó, nếu các phần tử có thể thay đổi, khi một phần tử được cập nhật, phần tử kia cũng được cập nhật. Trong trường hợp của một immutable, khi nó được cập nhật lên một giá trị mới, nó sẽ trở thành một đối tượng khác, còn đối tượng kia vẫn là đối tượng ban đầu.
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 5
nguồn. copy_deepcopy. py
Điều tương tự không chỉ áp dụng cho danh sách các danh sách như trong ví dụ trên mà còn cho danh sách từ điển, từ điển lồng nhau (từ điển có từ điển làm giá trị), v.v.
Lát cắt
Các lát cắt cho các loại trình tự có thể thay đổi, chẳng hạn như danh sách, cũng tạo các bản sao nông
- Cách cắt danh sách, chuỗi, tuple trong Python
Ví dụ: áp dụng lát cắt l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 42 chỉ định tất cả các phần tử sẽ tạo một bản sao nông của toàn bộ danh sách
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 7
nguồn. copy_deepcopy. py
Vì phương thức l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 đã được thêm vào các loại trình tự có thể thay đổi trong Python 3. 3, kỹ thuật tạo bản sao nông với l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 42 thường được sử dụng trước đây. Đối với mã mới, sẽ tốt hơn nếu sử dụng phương pháp l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 để làm cho ý định của bạn rõ ràng hơn
Một lát cho một phần cũng tạo ra một bản sao nông
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1
nguồn. copy_deepcopy. py
Nếu bạn muốn tạo một bản sao sâu, bạn có thể sử dụng chức năng i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False 0 để cắt lát
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 7, l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 8, v.v.
Bạn có thể tạo một bản sao nông của danh sách hoặc từ điển bằng cách chuyển danh sách tới l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 7 hoặc từ điển tới l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 8
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 7
nguồn. copy_deepcopy. py
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 5
Cũng có thể tạo một bản sao nông với chức năng l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 của mô-đun sao chép
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 0
nguồn. copy_deepcopy. py
Sử dụng l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 5 nếu bạn muốn tạo một bản sao nông của một đối tượng mà phương thức l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 1 không được cung cấp
Bản sao sâu. i1 = 1 i2 = i1 print(i1 is i2) # True i1 += 100 print(i1) # 101 print(i2) # 1 print(i1 is i2) # False 0
Để tạo một bản sao sâu, hãy sử dụng chức năng l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 3 của mô-đun sao chép
l1 = [0, 1, [2, 3]] l2 = l1 print(l1 is l2) # True l1[1] = 100 l1[2][0] = 200 print(l1) # [0, 100, [200, 3]] print(l2) # [0, 100, [200, 3]] print(l1 is l2) # True 5
nguồn. copy_deepcopy. py
Trong một bản sao sâu, các bản sao được chèn vào thay vì tham chiếu đến các đối tượng, vì vậy việc thay đổi cái này không làm thay đổi cái kia