Danh sách là cấu trúc dữ liệu thường được sử dụng trong Python. Chúng ta sẽ thường gặp các tình huống trong đó chúng ta cần tạo một bản sao của danh sách và bạn có thể tự hỏi: "Làm cách nào để sao chép danh sách trong Python?"
Hướng dẫn này sẽ hướng dẫn bạn cách sao chép hoặc sao chép danh sách bằng một số kỹ thuật khác nhau
- Toán tử gán
- Cú pháp cắt lát
- Danh sách. phương thức sao chép []
- Bản sao chép. chức năng sao chép []
- Bản sao chép. hàm deepcopy[]
Chúng tôi cũng sẽ thảo luận chi tiết về cách sử dụng và các khía cạnh kỹ thuật của họ
Sao chép danh sách bằng toán tử gán
Giả sử bạn sử dụng toán tử gán [=] để sao chép một danh sách bằng cách gán một biến danh sách hiện có cho một biến danh sách mới. Trong trường hợp này, bạn không thực sự tạo một bản sao của danh sách; . Hãy mở rộng chi tiết và xem xét kỹ hơn
Giả sử chúng ta có biến danh sách,
print['Original List:', org_list]
print['Copied List:', cpy_list]
8, được định nghĩa như sauorg_list = [1, 2, ['a', 'b', 'c'], 3]
Sau đó, chúng tôi gán nó cho một biến mới,
print['Original List:', org_list]
print['Copied List:', cpy_list]
9, hy vọng sẽ tạo một bản sao của nó để sử dụng trong tương laicpy_list = org_list
Tuy nhiên, bạn cần biết biến
print['Original List:', org_list]
print['Copied List:', cpy_list]
9 không phải là bản sao thực sự của danh sách gốc. Bạn có thể hỏi, "Tại sao nó không phải là bản sao chính xác của danh sách gốc?" print['Original List:', org_list]
print['Copied List:', cpy_list]
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
Như mong đợi, các danh sách chứa các giá trị giống nhau. Nhưng, hãy xem điều gì sẽ xảy ra nếu chúng ta sửa đổi danh sách ban đầu
org_list.append['Dataquest']
print['Original List:', org_list]
print['Copied List:', cpy_list]
Original List: [1, 2, ['a', 'b', 'c'], 3, 'Dataquest']
Copied List: [1, 2, ['a', 'b', 'c'], 3, 'Dataquest']
Bất kỳ sửa đổi nào đối với danh sách gốc cũng sẽ thay đổi danh sách đã sao chép
Hình minh họa sau đây cho thấy điều gì đang xảy ra khi mã nguồn được thực thi
Trên thực tế, khi bạn gán một biến cho một biến khác, cả hai biến đều tham chiếu đến cùng một đối tượng trong bộ nhớ, không phải hai biến riêng biệt. Điều này có nghĩa là cả hai biến đều trỏ đến cùng một đối tượng thông qua các tham chiếu của chúng. Khi có nhiều hơn một biến tham chiếu đến cùng một đối tượng, nó được gọi là đối tượng hoặc tham chiếu được chia sẻ
Bất kỳ sửa đổi nào đối với một đối tượng có thể thay đổi được chia sẻ thông qua một trong các biến trỏ tới nó sẽ ảnh hưởng đến biến khác tham chiếu cùng một đối tượng
Vì vậy, việc sử dụng toán tử gán không tạo ra một bản sao thực sự của một danh sách;
Nhưng nếu chúng ta muốn tạo một bản sao độc lập của danh sách thì sao?
Các kỹ thuật sao chép nông
Chúng tôi vừa biết rằng các nhiệm vụ luôn lưu trữ các tham chiếu đến các đối tượng và không tạo một bản sao thực sự của các đối tượng đó. Tuy nhiên, điều cần thiết là phải biết rằng việc thay đổi một đối tượng có thể thay đổi sẽ ảnh hưởng đến các đối tượng khác sử dụng cùng một tham chiếu trong mã của chúng ta. Vì vậy, chúng ta cần cho Python biết rõ ràng để sao chép một đối tượng nếu chúng ta muốn nhiều hơn là chỉ một bản sao của tham chiếu đến đối tượng đó. Nói chung, có hai cách để tạo một bản sao độc lập của danh sách. một bản sao nông và một bản sao sâu. Phần này sẽ thảo luận về bản sao nông và các cách khác nhau để thực hiện nó
Nói một cách đơn giản, việc tạo một bản sao nông của danh sách phức hợp sẽ tạo ra một danh sách ghép mới và sử dụng các tham chiếu đến các đối tượng mà danh sách gốc đã sử dụng
GHI CHÚ. Một đối tượng phức hợp là một đối tượng có chứa các đối tượng khác, e. g. , danh sách hoặc từ điển
Sao chép nông bằng cách cắt danh sách
Để hiểu khái niệm bản sao nông, hãy bắt đầu với một ví dụ. Giả sử chúng ta có một danh sách ghép như sau
org_list = [1, 2, ['a', 'b', 'c'], 3]
Sau đó, chúng ta có thể tạo một bản sao nông của nó bằng cách sử dụng cú pháp cắt danh sách
org_list = [1, 2, ['a', 'b', 'c'], 3]
0Nếu chúng ta chạy các câu lệnh in sau đây, chúng ta có thể thấy, cả hai đều trả về các giá trị giống hệt nhau
print['Original List:', org_list]
print['Copied List:', cpy_list]
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
Bây giờ, hãy thêm một mục mới vào danh sách ban đầu và chạy lại các câu lệnh in
org_list.append['Dataquest']
print['Original List:', org_list]
print['Copied List:', cpy_list]
cpy_list = org_list
1Việc sửa đổi không ảnh hưởng đến danh sách đã sao chép. Nhưng, đây không phải là toàn bộ câu chuyện. Hãy thử một kịch bản khác và thay đổi một trong các mục trong danh sách lồng nhau để xem điều gì sẽ xảy ra
cpy_list = org_list
2____33Mặc dù việc tạo một bản sao nông của danh sách sẽ tạo ra một bản sao thực sự của danh sách gốc, bất kỳ sửa đổi nào đối với các phần tử lồng nhau trong danh sách đó sẽ được phản ánh trong cả hai danh sách. Lý do là danh sách lồng nhau trong danh sách được sao chép sử dụng cùng một tham chiếu được chia sẻ như danh sách trong danh sách gốc. Nói cách khác, các danh sách lồng nhau trong danh sách được sao chép được gắn với các danh sách lồng nhau trong danh sách gốc. Đây là lý do tại sao chúng tôi gọi nó là bản sao nông — bởi vì chỉ một đối tượng cấp cao nhất mới được tạo trong khi mọi thứ sâu hơn sử dụng tham chiếu chung với danh sách gốc
Bây giờ, hãy xem xét một số cách khác để tạo bản sao nông của danh sách
Phương thức Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
1 của Python
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
Trước đó, chúng ta đã thảo luận về việc tạo một bản sao nông thông qua cú pháp cắt lát. Trong phần này, chúng ta sẽ tìm hiểu về một phương thức tích hợp sẵn mà các lập trình viên Python thường sử dụng để sao chép danh sách. Phương thức Python
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
2 trả về một bản sao nông của danh sách mà không lấy bất kỳ tham số nào. Hãy thử nó racpy_list = org_list
4cpy_list = org_list
5Mặc dù
print['Original List:', org_list]
print['Copied List:', cpy_list]
8 và print['Original List:', org_list]
print['Copied List:', cpy_list]
9 có cùng giá trị, như đầu ra từ hàm Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
5 cho thấy, chúng kết thúc ở các vị trí khác nhau trong bộ nhớ. Tuy nhiên, việc hiển thị địa chỉ bộ nhớ của danh sách bên trong trong cả danh sách gốc và danh sách được sao chép cho thấy rằng chúng đề cập đến cùng một vị trí trong bộ nhớ, nghĩa là chúng tôi đã tạo một bản sao nông của danh sách gốccpy_list = org_list
6cpy_list = org_list
7Hàm Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
6 của Python
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
Một cách hữu ích khác để tạo một bản sao nông của danh sách là hàm
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
6. Để sử dụng, chúng ta import mô-đun Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
8 rồi chuyển danh sách muốn sao chép vào hàm Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
6. Hãy thử nó racpy_list = org_list
8cpy_list = org_list
9Bây giờ, hãy thêm một mục mới vào danh sách ban đầu, in lại cả hai danh sách và kiểm tra đầu ra;
print['Original List:', org_list]
print['Copied List:', cpy_list]
0print['Original List:', org_list]
print['Copied List:', cpy_list]
1Phương pháp
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
6 đã tạo một bản sao thực sự của danh sách gốc. Tuy nhiên, 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, hàm Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
6 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. Vì vậy, bất kỳ sửa đổi nào trong các đối tượng lồng nhau của danh sách gốc hoặc danh sách được sao chép đều phản ánh trong các đối tượng lồng nhau của danh sách khácprint['Original List:', org_list]
print['Copied List:', cpy_list]
2____03Nếu chúng ta muốn có một bản sao hoàn toàn độc lập của một danh sách được lồng sâu thì sao?
Hàm org_list.append['Dataquest']
print['Original List:', org_list]
print['Copied List:', cpy_list]
2 của Python
org_list.append['Dataquest']
print['Original List:', org_list]
print['Copied List:', cpy_list]
Hàm
org_list.append['Dataquest']
print['Original List:', org_list]
print['Copied List:', cpy_list]
2 duyệt qua một cách đệ quy một danh sách để tạo các bản sao của từng đối tượng lồng nhau của nó. Nói cách khác, nó tạo một bản sao cấp cao nhất của danh sách và sau đó thêm đệ quy các bản sao của các đối tượng lồng nhau từ danh sách ban đầu vào bản sao mới. Điều này tạo ra một bản sao hoàn toàn độc lập với danh sách ban đầu và bất kỳ thay đổi nào được thực hiện đối với các đối tượng lồng nhau của một trong hai sẽ không được phản ánh trong danh sách kiaGiống như hàm
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
6, hàm org_list.append['Dataquest']
print['Original List:', org_list]
print['Copied List:', cpy_list]
2 thuộc module Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
8. Hãy thử nó raprint['Original List:', org_list]
print['Copied List:', cpy_list]
4print['Original List:', org_list]
print['Copied List:', cpy_list]
5Đầu ra của mã ở trên cho thấy rõ ràng rằng
org_list.append['Dataquest']
print['Original List:', org_list]
print['Copied List:', cpy_list]
2 đã tạo một bản sao thực sự của danh sách gốc và ngay cả khi chúng tôi sửa đổi danh sách bên trong của danh sách gốc, nó sẽ không được phản ánh trong danh sách được sao chép sâuprint['Original List:', org_list]
print['Copied List:', cpy_list]
6print['Original List:', org_list]
print['Copied List:', cpy_list]
7Đoạn mã trên cho thấy rằng khi chúng ta tạo một bản sao sâu của một danh sách, nó cũng tạo ra các bản sao thực sự của các đối tượng lồng nhau. Như đã đề cập trước đó, bản sao sâu đệ quy tạo ra một bản sao thực sự độc lập của danh sách gốc, đó là lý do tại sao danh sách bên trong trong danh sách gốc và danh sách được sao chép trỏ đến hai vị trí bộ nhớ khác nhau. Rõ ràng, bất kỳ thay đổi nào được thực hiện đối với danh sách bên trong của danh sách này sẽ không được phản ánh trong danh sách kia
Sự kết luận
Hướng dẫn này đã thảo luận về một số cách khác nhau để sao chép danh sách trong Python, chẳng hạn như toán tử gán, cú pháp cắt danh sách, các hàm
Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
1, Original List: [1, 2, ['a', 'b', 'c'], 3]
Copied List: [1, 2, ['a', 'b', 'c'], 3]
6 và Original List: [1, 2, ['a', 'b', 'c'], 3, 'Dataquest']
Copied List: [1, 2, ['a', 'b', 'c'], 3, 'Dataquest']
0. Ngoài ra, chúng tôi đã thảo luận về các bản sao nông và sâu. Tôi hy vọng hướng dẫn này sẽ giúp bạn hiểu rõ hơn về các cách sao chép danh sách khác nhau trong Python vì chúng rất quan trọng để trở thành một Pythonistahướng dẫn khoa học dữ liệu python
Thông tin về các Tác giả
Mehdi Lotfinejad
Mehdi là Kỹ sư dữ liệu cao cấp và Trưởng nhóm tại ADA. Anh ấy là một huấn luyện viên chuyên nghiệp, người thích viết các hướng dẫn phân tích dữ liệu