Việc sao chép danh sách trong Python không đơn giản chỉ là gán giá trị từ danh sách này sang danh sách khác. Có nhiều phương pháp khác nhau để thực hiện việc này, mỗi phương pháp có những đặc điểm và ứng dụng riêng. Bài viết này sẽ đi sâu vào một số khía cạnh của việc sao chép danh sách. Giúp bạn hiểu rõ hơn về các cách copy list trong Python một cách đầy đủ và chi tiết.
Các điểm chính
Khi đọc xong bài viết, bạn sẽ:
- Nắm vững các khái niệm cơ bản về copy list trong Python: Bạn sẽ hiểu rõ sự khác biệt giữa việc gán list và thực sự tạo bản sao. Điều này cực kỳ quan trọng để tránh những lỗi không mong muốn khi làm việc với list.
- Phân biệt và hiểu rõ shallow copy và deep copy: Bạn sẽ hiểu rõ hai khái niệm này, khi nào cần sử dụng shallow copy, khi nào cần dùng deep copy, và tại sao lại như vậy. Đây là kiến thức nền tảng để xử lý dữ liệu phức tạp.
- Biết cách sử dụng nhiều phương pháp copy list khác nhau: Bạn sẽ được làm quen với Slice Notation, hàm
list()
, và hàmcopy()
, hiểu ưu và nhược điểm của từng phương pháp, từ đó lựa chọn cách phù hợp nhất với từng tình huống cụ thể. - Ứng dụng kiến thức vào thực tế: Bài viết không chỉ lý thuyết suông, mà sẽ giúp bạn áp dụng các phương pháp copy list vào các bài toán thực tế khi lập trình.
Copy list trong Python
Copy một List trong Python là tạo ra một List mới chứa các phần tử giống hệt như List ban đầu. Có nhiều phương pháp khác nhau để copy một List, bao gồm: sử dụng kỹ thuật slice, hàm list()
, và phương thức copy()
.

Mỗi phương pháp này có những đặc điểm khác nhau, tạo ra các bản sao shallow hoặc deep. Chúng ta sẽ tìm hiểu sâu về tất cả các phương pháp này trong phần hướng dẫn sau.
Shallow copy trên List trong Python
Shallow copy trong Python tạo ra một đối tượng mới, nhưng thay vì copy các phần tử một cách đệ quy, shallow copy chỉ copy các tham chiếu đến các phần tử gốc. Điều này có nghĩa là đối tượng mới là một thực thể riêng biệt với đối tượng ban đầu, nhưng nếu bản thân các phần tử là kiểu dữ liệu có thể thay đổi (mutable), thì những thay đổi được thực hiện đối với các phần tử đó trong đối tượng mới cũng sẽ ảnh hưởng đến đối tượng ban đầu.
Ví dụ:
import copy
# List ban đầu
danh_sach_ban_dau = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# Tạo một bản sao nông (shallow copy)
danh_sach_sao_chep_nong = copy.copy(danh_sach_ban_dau)
# Thay đổi một phần tử trong bản sao nông
danh_sach_sao_chep_nong[0][0] = 100
# In ra cả hai List
print("List Ban Đầu:", danh_sach_ban_dau)
print("List Sao Chép Nông:", danh_sach_sao_chep_nong)
Kết quả bạn nhận được sẽ là:
List Ban Đầu: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
List Sao Chép Nông: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
Giải thích:
import copy
: Dòng này nhập modulecopy
để sử dụng các chức năng liên quan đến sao chép.danh_sach_ban_dau = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
: Khởi tạo một List ban đầu, đây là một List chứa các List con bên trong.danh_sach_sao_chep_nong = copy.copy(danh_sach_ban_dau)
: Tạo một bản sao nông (shallow copy) củadanh_sach_ban_dau
sử dụng hàmcopy.copy()
.danh_sach_sao_chep_nong[0][0] = 100
: Thay đổi giá trị của phần tử đầu tiên trong List con đầu tiên củadanh_sach_sao_chep_nong
.print(...)
: In ra cả hai List.
Deep copy trên list trong Python
Deep copy trong Python tạo ra một đối tượng hoàn toàn mới và copy một cách đệ quy tất cả các đối tượng được tham chiếu bởi đối tượng ban đầu. Điều này có nghĩa là, thậm chí các đối tượng lồng nhau (nested objects) bên trong đối tượng gốc cũng được nhân bản. Kết quả là chúng ta có một bản sao hoàn toàn độc lập. Các thay đổi được thực hiện trên bản sao sẽ không ảnh hưởng đến bản gốc và ngược lại.
Ví dụ:
import copy
# List gốc
danh_sach_ban_dau = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# Tạo một deep copy
danh_sach_sao_chep_sau = copy.deepcopy(danh_sach_ban_dau)
# Thay đổi một phần tử trong bản deep copy
danh_sach_sao_chep_sau[0][0] = 100
# In ra cả hai List
print("List Ban Đầu:", danh_sach_ban_dau)
print("List Sao Chép Sâu:", danh_sach_sao_chep_sau)
Khi bạn chạy đoạn code trên, kết quả sẽ như sau:
List Ban Đầu: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
List Sao Chép Sâu: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
Giải thích code:
import copy
: Dòng này nhập (import
) modulecopy
. Module này cung cấp các hàm để thực hiện sao chép nông (shallow copy) và sao chép sâu (deep copy).danh_sach_ban_dau = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
: Khởi tạo mộtList
ban đầu.List
này chứa cácList
con bên trong.danh_sach_sao_chep_sau = copy.deepcopy(danh_sach_ban_dau)
: Dòng này tạo một bản sao sâu (deep copy) củadanh_sach_ban_dau
bằng cách sử dụng hàmdeepcopy()
từ modulecopy
.danh_sach_sao_chep_sau[0][0] = 100
: Thay đổi giá trị của phần tử đầu tiên trongList
con đầu tiên củadanh_sach_sao_chep_sau
thành 100.print("List Ban Đầu:", danh_sach_ban_dau)
vàprint("List Sao Chép Sâu:", danh_sach_sao_chep_sau)
: In ra cảList
ban đầu vàList
đã được sao chép sâu.
Copy list trong Python bằng Slice Notation
Slice notation trong Python cho phép bạn tạo ra một chuỗi con (subsequence) các phần tử từ một chuỗi (như List, tuple, hoặc string) bằng cách chỉ định chỉ số bắt đầu, chỉ số kết thúc và một bước nhảy (tùy chọn). Cú pháp của slice notation như sau:
[start:end:step]
Trong đó, start là chỉ mục nơi đoạn cắt bắt đầu, end là chỉ mục nơi đoạn cắt kết thúc (không bao gồm), và step là kích thước bước giữa các phần tử.
Trong đó:
- start: là chỉ số nơi phần cắt (slice) bắt đầu.
- end: là chỉ số nơi phần cắt kết thúc (không bao gồm phần tử tại chỉ số end).
- step: là kích thước bước nhảy giữa các phần tử (có thể bỏ qua, mặc định là 1).
Chúng ta có thể copy một List bằng cách sử dụng slice notation để chỉ định toàn bộ phạm vi chỉ số của List gốc. Thao tác này sẽ tạo ra một List mới với các phần tử giống hệt List ban đầu.
Bất kỳ sửa đổi nào được thực hiện trên List đã copy sẽ không ảnh hưởng đến List gốc và ngược lại, vì hai List này là các đối tượng riêng biệt trong bộ nhớ.
Trong ví dụ này, chúng ta sẽ tạo một “lát cắt” (slice) của original_list, copy một phần tử từ nó vào một List mới có tên là copied_list
:
# List gốc
original_list = [1, 2, 3, 4, 5]
# Sao chép List sử dụng slice notation
copied_list = original_list[1:4]
# Thay đổi List đã sao chép
copied_list[0] = 100
# In ra cả hai List
print("Original List:", original_list)
print("Copied List:", copied_list)
Kết quả chúng ta nhận được như sau:
Original List: [1, 2, 3, 4, 5]
Copied List: [100, 3, 4]
Giải thích:
original_list = [1, 2, 3, 4, 5]
: Tạo một List ban đầu có tênoriginal_list
với 5 phần tử.copied_list = original_list[1:4]
: Đây là phần quan trọng! Dòng này sử dụng slice notation:[1:4]
: có nghĩa là tạo một List mới bắt đầu từ phần tử có chỉ số 1 (phần tử thứ hai trongoriginal_list
vì chỉ số bắt đầu từ 0) đến phần tử có chỉ số 4 (nhưng không bao gồm phần tử có chỉ số 4). Vậy nêncopied_list
ban đầu sẽ chứa các phần tử[2, 3, 4]
lấy từoriginal_list
.
copied_list[0] = 100
: Thay đổi phần tử đầu tiên củacopied_list
(có chỉ số 0) thành 100.print("Original List:", original_list)
vàprint("Copied List:", copied_list)
: In ra hai List. Kết quả cho thấyoriginal_list
không bị ảnh hưởng (vẫn là[1, 2, 3, 4, 5]
), còncopied_list
đã được thay đổi ([100, 3, 4]
).
Copy list trong Python với hàm list()
Hàm list() trong Python là một hàm có sẵn dùng để tạo một đối tượng List mới. Hàm này có thể nhận một đối tượng có thể lặp làm đối số và tạo ra một List mới chứa các phần tử của đối tượng đó. Nếu không có đối số nào được truyền vào, một List rỗng sẽ được tạo.
Chúng ta có thể sao chép một List bằng cách sử dụng hàm list()
và truyền List gốc vào làm đối số. Thao tác này sẽ tạo ra một đối tượng List mới chứa các phần tử giống hệt như List ban đầu.
Trong ví dụ dưới đây, chúng ta tạo một đối tượng List mới tên là "copied_list"
chứa các phần tử giống hệt như “original_list” bằng cách sử dụng hàm list()
:
# Original list
original_list = [1, 2, 3, 4, 5]
# Copying the list using the list() constructor
copied_list = list(original_list)
# Printing both lists
print("Original List:", original_list)
print("Copied List:", copied_list)
Kết quả khi chạy đoạn code trên:
Original List: [1, 2, 3, 4, 5]
Copied List: [1, 2, 3, 4, 5]
Giải thích chi tiết:
original_list = [1, 2, 3, 4, 5]
: Dòng này tạo một List có tênoriginal_list
và chứa các số nguyên từ 1 đến 5.copied_list = list(original_list)
: Đây là điểm quan trọng. Dòng này thực hiện việc sao chép.- Hàm
list()
được gọi. original_list
được truyền vào hàmlist()
làm đối số.- Hàm
list()
tạo một đối tượng List mới hoàn toàn. Đối tượng List mới này có các phần tử giống hệtoriginal_list
. - Đối tượng List mới này được gán cho biến
copied_list
.
- Hàm
print("Original List:", original_list)
vàprint("Copied List:", copied_list)
: Hai dòng này in ra nội dung của cả hai List để chúng ta thấy được kết quả.
Copy list bằng hàm copy() trong Python
Trong Python, hàm copy()
được sử dụng để tạo một bản sao “nông” (shallow copy) của một List hoặc các đối tượng khả biến khác. Hàm này là một phần của module copy trong thư viện chuẩn của Python.
Chúng ta có thể copy một List bằng cách sử dụng hàm copy()
trên List gốc. Thao tác này sẽ tạo ra một đối tượng List mới chứa các phần tử giống hệt như List ban đầu.
Trong ví dụ sau, chúng ta sử dụng hàm copy()
để tạo một đối tượng List mới có tên danh_sach_ban_sao
chứa các phần tử tương tự như danh_sach_goc
:
import copy
danh_sach_goc = [1, 2, 3, 4, 5]
# Sao chép List sử dụng hàm copy()
danh_sach_ban_sao = copy.copy(danh_sach_goc)
print("List đã sao chép:", danh_sach_ban_sao)
Kết quả:
List đã sao chép: [1, 2, 3, 4, 5]
Giải thích:
import copy
: Dòng này nhập modulecopy
vào chương trình. Modulecopy
chứa hàmcopy()
và các hàm khác liên quan đến việc sao chép đối tượng.danh_sach_goc = [1, 2, 3, 4, 5]
: Khởi tạo một List có têndanh_sach_goc
với các giá trị số nguyên.danh_sach_ban_sao = copy.copy(danh_sach_goc)
: Dòng này thực hiện việc sao chép.copy.copy(danh_sach_goc)
: Gọi hàmcopy()
từ modulecopy
và truyềndanh_sach_goc
làm đối số.- Kết quả trả về của hàm
copy()
(tức là bản sao của List) được gán cho biếndanh_sach_ban_sao
. print("List đã sao chép:", danh_sach_ban_sao)
: In ra màn hình nội dung củadanh_sach_ban_sao
để kiểm tra.
Lời kết
Chúng ta vừa cùng nhau khám phá chi tiết các phương pháp copy list trong Python, từ shallow copy đến deep copy, sử dụng slice notation, hàm list(), và hàm copy(). Mỗi kỹ thuật có những ưu điểm và trường hợp sử dụng riêng. Hy vọng rằng, với những kiến thức này, bạn có thể lựa chọn cách copy list phù hợp nhất với nhu cầu lập trình của mình, giúp tối ưu hóa và đảm bảo tính chính xác cho dự án.
Mọi người cũng đọc