Python: Thao Tác Với Danh Sách (Thêm, Xóa, Sửa, Tra Cứu)

Thêm Phần Tử Vào Danh Sách

Phương thức .append()

ds_ten = []
# Thêm phần tử vào cuối danh sách
# append() thêm vào cuối
ds_ten.append("Nguyễn Văn A")
ds_ten.append("Trần Thị B")
ds_ten.append("Lê Văn C")
print(ds_ten)
# insert() chèn vào vị trí chỉ định, các phần tử sau vị trí đó sẽ dịch chuyển
ds_ten.insert(0, "Phạm Thị D")    # Chèn vào vị trí 0
print(ds_ten)
# extend() hợp nhất hai danh sách, thêm hàng loạt
ds_ten.extend(['Văn E', "Thị F", "G Văn"])
print(ds_ten)

Kết quả:

['Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C']
['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C']
['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C', 'Văn E', 'Thị F', 'G Văn']

Xóa Phần Tử Khỏi Danh Sách

Cả lệnh del, phương thức .remove() hay .pop() đều thao tác trực tiếp trên danh sách gốc, khác với các thao tác trên chuỗi trước đó.

Để xóa nhiều phần tử, cách tốt nhất là xóa từ cuối danh sách về đầu, nếu không vị trí các phần tử sẽ thay đổi.

del ds_ten - xóa toàn bộ danh sách

del ds_ten[] - xóa phần tử trong danh sách

Để minh họa sự khác biệt khi xóa từ trước ra sau và từ sau ra trước:

ds = ['0', '1', '2', '3', '4', '5', '6']
# Xóa các phần tử theo chỉ số từ cao đến thấp
del ds[5]  # Xóa phần tử ở chỉ số 5
print(ds)
del ds[3]  # Xóa phần tử ở chỉ số 3
print(ds)
del ds[1]  # Xóa phần tử ở chỉ số 1
print(ds)

#Kết quả:
['0', '1', '2', '3', '4', '6']
['0', '1', '2', '4', '6']
['0', '2', '4', '6']

Nếu xóa từ trước ra sau, vị trí các phần tử sẽ thay đổi, độ dài danh sách sẽ giảm, có thể dẫn đến lỗi chỉ số vượt phạm vi:

# Xóa
ds = ['0', '1', '2', '3', '4', '5', '6']
# Xóa các phần tử theo chỉ số từ thấp đến cao
del ds[1]  # Xóa phần tử ở chỉ số 1
print(ds)
del ds[3]  # Xóa phần tử ở chỉ số 3
print(ds)
del ds[5]  # Xóa phần tử ở chỉ số 5
print(ds)

#Kết quả
['0', '2', '3', '4', '5', '6']
['0', '2', '3', '5', '6']
Traceback (most recent call last):
  File "D:\Python\danh_sach\phuong_thuc_xoa.py", line 43, in <module>
    del ds[5]  # Xóa phần tử ở chỉ số 5
        ~~~^^^
IndexError: list assignment index out of range

Lệnh del cần chỉ số phần tử, trong khi .remove() có thể tránh được vấn đề này.

Sử dụng .remove() để xóa phần tử không cần biết vị trí:

ds_ten = ['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C', 'Văn E', 'Thị F', 'G Văn']
ds_ten.remove("G Văn")  # Xóa phần tử cụ thể
print(ds_ten)

Sử dụng phương thức .pop() để xóa

pop() là phương thức của danh sách (list) trong Python, dùng để xóa và trả về phần tử ở vị trí chỉ định. Phương thức này có thể có tham số tùy chọn để chỉ định chỉ số phần tử cần xóa, nếu không chỉ định thì mặc định xóa và trả về phần tử cuối cùng (-1).

Cú pháp:

gia_tri = danh_sach.pop(chi_so)
  • danh_sach: danh sách cần thao tác
  • chi_so: chỉ số phần tử cần xóa. Nếu không cung cấp, mặc định là -1, tức là xóa và trả về phần tử cuối cùng
  • gia_tri: phần tử bị xóa, cũng được pop() trả về
hoaqua = ["táo", "chuối", "nho"]

# Xóa và trả về phần tử ở chỉ số 1
qua_loai = hoaqua.pop(1)

print(qua_loai)  # Xuất: "chuối"
print(hoaqua)    # Xuất: ["táo", "nho"]

Phương thức pop() sẽ sửa đổi danh sách gốc và trả về phần tử bị xóa, vì vậy bạn có thể gán nó cho một biến để sử dụng sau này. Nếu không cung cấp tham số chỉ số, nó sẽ mặc định xóa và trả về phần tử cuối cùng. Nếu chỉ số vượt quá phạm vi danh sách, sẽ ném ra ngoại lệ IndexError.

Sửa Đổi Phần Tử

ds_ten = ['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C', 'Văn E', 'Thị F', 'G Văn']
ds_ten[4] = "H Văn"  # Sửa trực tiếp bằng chỉ số
print(ds_ten)

#Kết quả
['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C', 'H Văn', 'Thị F', 'G Văn']

Tìm Kiếm Phần Tử

ds_ten = ['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C', 'H Văn', 'Thị F', 'G Văn']
print(ds_ten[4])  # Tìm kiếm trực tiếp bằng chỉ số

#Kết quả
H Văn

Bài tập nhỏ: Thay đổi tất cả những người có họ "Nguyễn" thành họ "Trần", các tên khác giữ nguyên

ds_ten = ['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C', 'Văn E', 'Thị F', 'Nguyễn Văn G']

for i in range(len(ds_ten)):  # len(ds_ten) độ dài danh sách -> lấy chỉ số trong vòng lặp
    item = ds_ten[i]  # item vẫn là mỗi phần tử trong danh sách
    if item.startswith("Nguyễn"):
        # Nguyễn Văn A
        new_name = "Trần"+item[3:]
        print(new_name)
        # Đặt tên mới vào danh sách (cần chỉ số?)
        ds_ten[i] = new_name  # Sửa

print(ds_ten)

Giải thích chi tiết có thể tham khảo bài giới thiệu về range

https://www.cnblogs.com/Magiclala/p/17774977.html

Xóa Trong Vòng Lặp Danh Sách (*)

Cách làm sai

ds_ten = ['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Văn E', 'Thị F', 'Nguyễn Văn G']

for item in ds_ten:
    if item.startswith("Nguyễn"):
        ds_ten.remove(item)  # Có lỗi
print(ds_ten)

Kết quả:

['Phạm Thị D', 'Trần Thị B', 'Văn E', 'Thị F', 'Nguyễn Văn G']

Mã trên có mục tiêu xóa tất cả các phần tử bắt đầu bằng "Nguyễn" khỏi danh sách. Tuy nhiên, mã này trong Python có một vấn đề phổ biến. Khi bạn cố gắng sửa đổi một danh sách trong khi đang lặp qua nó, sẽ xảy ra lỗi. Việc sửa đổi danh sách trong quá trình lặp sẽ ảnh hưởng đến trạng thái của bộ lặp.

Nguyên lý thực hiện vòng lặp for item in ds_ten:

  1. Vòng lặp for thực hiện theo vị trí con trích để lặp lần lượt.
  2. Trong quá trình đếm, con trỏ của vòng lặp for thực hiện vị trí 0 là 'Phạm Thị D', sau khi kiểm tra không phù hợp, con trỏ chuyển đến vị trí 1 là 'Nguyễn Văn A'. Lúc này 'Nguyễn Văn A' phù hợp với điều kiện startswith("Nguyễn"), do đó thực hiện thao tác ds_ten.remove(item). Sau khi thực hiện thao tác xóa, vị trí 1 ngay lập tức trống, các vị trí gốc (2 là 'Trần Thị B', 3 là 'Văn E', 4 là 'Thị F', 5 là 'Nguyễn Văn G') đều chuyển thành (1 là 'Trần Thị B', 2 là 'Văn E', 3 là 'Thị F', 4 là 'Nguyễn Văn G').
  3. Sau đó vòng lặp cần tiếp tục chuyển xuống, con trỏ chuyển đến vị trí sau đó là vị trí 2 'Văn E', lặp lại các thao tác trên. Vị trí 3 'Thị F', vị trí 4 'Nguyễn Văn G'
  4. Vị trí gốc 2 là 'Trần Thị B' lại vì chuyển thành vị trí 1 nên bị vòng lặp for bỏ qua thực hiện.
  5. Vì vậy 'Trần Thị B' không bị xóa.

Vì vậy, trong tiêu chuẩn ngành, chúng ta mặc định không thực hiện thao tác xóa trực tiếp trên danh sách gốc trong vòng lặp.

Cách xóa trong vòng lặp an toàn và ổn định là: lưu trữ các phần tử cần xóa vào một danh sách mới. Sau đó dùng vòng lặp để lấy từng phần tử trong danh sách mới, xóa khỏi danh sách cũ.

ds_ten = ['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Văn E', 'Thị F', 'Nguyễn Văn G']

tam = [] # Chuẩn bị một danh sách tạm, dùng để lưu trữ nội dung cần xóa
for item in ds_ten:
    if item.startswith("Nguyễn"):
        tam.append(item)  # Thêm nội dung cần xóa vào danh sách tam

for item in tam:
    ds_ten.remove(item)  # Lấy các phần tử trong danh sách tam, xóa trong danh sách gốc, tránh vấn đề chỉ số
print(ds_ten)

Cũng có thể tạo một danh sách mới, thêm tất cả các phần tử không muốn xóa từ danh sách cũ vào đó. Ví dụ:

ds_ten = ['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Văn E', 'Thị F', 'Nguyễn Văn G']
tam = []
for item in ds_ten:
    if not item.startswith("Nguyễn"):
        tam.append(item)
print(tam)

Ngoài ra, có thể sử dụng biểu thức danh sách (list comprehension) để tạo một danh sách mới, chứa các phần tử không bị xóa. Ví dụ:

ds_ten = ['Phạm Thị D', 'Nguyễn Văn A', 'Trần Thị B', 'Văn E', 'Thị F', 'Nguyễn Văn G']
ds_ten = [item for item in ds_ten if not item.startswith("Nguyễn")]
print(ds_ten)

Đây là cách sử dụng phổ biến của biểu thức danh sách, dùng để lọc và chuyển đổi các phần tử trong danh sách dựa trên điều kiện cụ thể, và tên danh sách gốc không thay đổi.

Quá trình thực hiện:

  1. Duyệt qua từng phần tử item trong danh sách gốc ds_ten.
  2. Đối với mỗi phần tử item, kiểm tra xem nó có bắt đầu bằng "Nguyễn" không. - Nếu item bắt đầu bằng "Nguyễn", điều kiện item.startswith("Nguyễn")True. - Nếu item không bắt đầu bằng "Nguyễn", điều kiện item.startswith("Nguyễn")False.
  3. Nếu điều kiện là False, thêm phần tử item vào danh sách mới.
  4. Tiếp tục duyệt qua phần tử tiếp theo trong danh sách gốc, lặp lại bước 2 và bước 3.
  5. Sau khi hoàn thành việc duyệt toàn bộ danh sách gốc, tạo danh sách mới hoàn chỉnh.
  6. Gán danh sách mới này cho biến ds_ten[].

Vì vậy, cuối cùng danh sách gốc ds_ten đã được sửa đổi, bây giờ nó chứa các phần tử không bắt đầu bằng "Nguyễn".

Thẻ: python danh_sach list_operations python_list

Đăng vào ngày 15 tháng 7 lúc 01:55