Bản sao sâu và nông trong python là gì?

Độ sâu một cấp. Sửa ở mức 1 không ảnh hưởng đến danh sách khác. Sử dụng

[-10, 2, 3, 4, 5]
[-10, 2, 3, 4, 5]
7 hoặc các hàm sao chép/hàm tạo sao chép dành riêng cho đối tượng

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

import copy

l = [0, 1, [2, 3]]
l_assign = l                   # assignment
l_copy = l.copy[]              # shallow copy
l_deepcopy = copy.deepcopy[l]  # deep copy

l[1] = 100
l[2][0] = 200
print[l]
# [0, 100, [200, 3]]

print[l_assign]
# [0, 100, [200, 3]]

print[l_copy]
# [0, 1, [200, 3]]

print[l_deepcopy]
# [0, 1, [2, 3]]

nguồn.

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.

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

Để 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 thể thay đổi 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.

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

l = [0, 1, [2, 3]]
l_copy = l.copy[]

print[l is l_copy]
# False

print[l[2] is l_copy[2]]
# True

nguồn.

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.

l[1] = 100
l[2][0] = 200
print[l]
# [0, 100, [200, 3]]

print[l_copy]
# [0, 1, [200, 3]]

print[l[2] is l_copy[2]]
# True

nguồn.

Đ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

l = [0, 1, [2, 3]]
l_copy = l.copy[]

print[l is l_copy]
# False

print[l[2] is l_copy[2]]
# True
2 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

l = [0, 1, [2, 3]]
l_whole_slice = l[:]

l[1] = 100
l[2][0] = 200
print[l]
# [0, 100, [200, 3]]

print[l_whole_slice]
# [0, 1, [200, 3]]

nguồn.

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
l = [0, 1, [2, 3]]
l_copy = l.copy[]

print[l is l_copy]
# False

print[l[2] is l_copy[2]]
# True
2 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

l = [0, 1, [2, 3]]
l_slice = l[1:]
print[l_slice]
# [1, [2, 3]]

l[1] = 100
l[2][0] = 200
print[l]
# [0, 100, [200, 3]]

print[l_slice]
# [1, [200, 3]]

nguồn.

Nếu bạn muốn tạo một bản sao sâu, bạn có thể sử dụng 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ắ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 sơ ​​sài của danh sách hoặc từ điển bằng cách chuyển danh sách cho

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 cho
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

l = [0, 1, [2, 3]]
l_list = list[l]

l[1] = 100
l[2][0] = 200
print[l]
# [0, 100, [200, 3]]

print[l_list]
# [0, 1, [200, 3]]

nguồn.

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

l = [0, 1, [2, 3]]
l_copy = copy.copy[l]

l[1] = 100
l[2][0] = 200
print[l]
# [0, 100, [200, 3]]

print[l_copy]
# [0, 1, [200, 3]]

nguồn.

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

l = [0, 1, [2, 3]]
l_deepcopy = copy.deepcopy[l]

print[l is l_deepcopy]
# False

print[l[2] is l_deepcopy[2]]
# False

l[1] = 100
l[2][0] = 200
print[l]
# [0, 100, [200, 3]]

print[l_deepcopy]
# [0, 1, [2, 3]]

nguồn.

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

Bản sao sâu so với bản sao nông là gì?

Một bản sao sâu xảy ra khi một đối tượng được sao chép cùng với các đối tượng mà nó tham chiếu tới. Bản sao nông là bản sao một đối tượng thông minh một chút . Một đối tượng mới được tạo có bản sao chính xác của các giá trị trong đối tượng ban đầu.

Bản sao nông và bản sao sâu Python là gì?

Một bản sao nông tạo ra một đối tượng ghép mới và sau đó thêm một tham chiếu đến đối tượng được tìm thấy trong bản gốc. Một bản sao sâu tạo một đối tượng phức hợp mới và sau đó thêm một tham chiếu đến đối tượng được tìm thấy trong bản gốc. Chúng ta có thể sao chép các đối tượng tùy ý [bao gồm cả các lớp tùy chỉnh] bằng mô-đun sao chép

Python tạo bản sao sâu hay nông?

Để tạo các bản sao này, chúng tôi sử dụng mô-đun sao chép. Bản sao[] trả về một bản sao nông của danh sách và deepcopy[] trả về một bản sao sâu của danh sách . Như bạn có thể thấy rằng cả hai đều có cùng giá trị nhưng có ID khác nhau.

Bản sao sâu với ví dụ là gì?

Bản sao sâu của đối tượng là bản sao có thuộc tính không chia sẻ cùng tham chiếu [trỏ đến cùng giá trị cơ bản] như thuộc tính của đối tượng nguồn mà từ đó bản sao được tạo ra . .

Chủ Đề