Chọn đến phần học sinh cần nhanh chóng thông qua mục lục bằng cách click đến phần đó
- I. Lý thuyết trọng tâm
- 1. Duyệt danh sách với toán tử in
- 2. Một số phương thức làm việc với danh sách
- II. Phương pháp giải các dạng bài tập
- Dạng 1: Xác định kết quả khi dùng toán tử in và các phương thức
- Dạng 2: Chèn phần tử vào danh sách bằng insert()
- Dạng 3: Xóa phần tử theo điều kiện bằng vòng lặp while + remove()
- Dạng 4: Tìm mẫu (pattern) trong danh sách
- III. Hướng dẫn thực hành
- Nhiệm vụ 1: Nhập danh sách tên học sinh, in theo thứ tự ngược
- Nhiệm vụ 2: Xóa các phần tử âm khỏi danh sách
- Nhiệm vụ 3: Tìm mẫu [1, 2, 3] trong dãy số
- IV. Sơ đồ tư duy
- V. Sai lầm thường gặp
I. Lý thuyết trọng tâm
1. Duyệt danh sách với toán tử in
Toán tử in có hai công dụng khi làm việc với danh sách:
a) Kiểm tra phần tử có trong danh sách không
Cú pháp:
<giá_trị> in <danh_sách>
Kết quả trả về True nếu giá trị có trong danh sách, False nếu không có.
>>> A = [1, 2, 3, 4, 5]
>>> 2 in A
True # số 2 có trong A
>>> 10 in A
False # số 10 không có trong A
⚠️ Lưu ý kiểu dữ liệu: Toán tử
inso sánh chính xác cả giá trị lẫn kiểu dữ liệu. Số nguyên1và xâu kí tự"1"là hai giá trị khác nhau.
Câu hỏi kiểm tra nhanh: Cho A = ["0", "1", "01", "10"]. Các biểu thức sau trả về đúng hay sai?
1 in A→ False. Vì1là số nguyên, trong khi danh sách A chỉ chứa các xâu kí tự ("1"≠ 1)."01" in A→ True. Vì xâu"01"có trong danh sách A.
b) Duyệt từng phần tử bằng for...in
Cú pháp:
for <biến> in <danh_sách>:
<các lệnh>
Biến sẽ lần lượt nhận trực tiếp giá trị của từng phần tử trong danh sách (không cần dùng chỉ số và range()).
>>> A = [10, 11, 12, 13, 14, 15]
>>> for k in A:
print(k, end=" ")
10 11 12 13 14 15
So sánh hai cách duyệt:
| Cách duyệt | Cú pháp | Biến nhận giá trị | Khi nào dùng |
|---|---|---|---|
for i in range(len(A)) |
Duyệt qua chỉ số | i = 0, 1, 2… → truy cập A[i] |
Cần biết vị trí phần tử, cần thay đổi giá trị |
for k in A |
Duyệt qua giá trị | k = giá trị từng phần tử |
Chỉ cần đọc giá trị, không cần chỉ số |
Câu hỏi kiểm tra nhanh: Giải thích ý nghĩa từ khóa in trong câu lệnh:
for i in range(10):
<các lệnh>
→ Ở đây in không phải kiểm tra phần tử có trong danh sách. Nó là một phần của cú pháp vòng lặp for, dùng để chỉ định biến i lần lượt nhận các giá trị trong range(10) (tức 0, 1, 2, …, 9).
2. Một số phương thức làm việc với danh sách
Ngoài append() đã học ở Bài 22, Python còn cung cấp thêm các phương thức quan trọng:
| Phương thức | Cú pháp | Chức năng |
|---|---|---|
| append(x) | A.append(x) |
Thêm phần tử x vào cuối danh sách A |
| insert(k, x) | A.insert(k, x) |
Chèn phần tử x vào vị trí k, đẩy các phần tử từ k trở đi sang phải |
| remove(x) | A.remove(x) |
Xóa phần tử đầu tiên có giá trị x. Nếu không tìm thấy → báo lỗi ValueError |
| clear() | A.clear() |
Xóa toàn bộ danh sách, biến A thành [] |
Chi tiết phương thức insert()
>>> A = [1, 2, 6, 10]
>>> A.insert(2, 5) # chèn số 5 tại chỉ số 2
>>> A
[1, 2, 5, 6, 10]
Trường hợp đặc biệt: Nếu chỉ số nằm ngoài phạm vi, lệnh vẫn hoạt động:
k < 0(hoặc nhỏ hơn chỉ số đầu) → chèn vào đầu danh sách.k > len(A)→ chèn vào cuối danh sách.
>>> A = []
>>> A.insert(-10, 1) # chèn 1 vào đầu (vì -10 < 0)
>>> A.insert(100, 2) # chèn 2 vào cuối (vì 100 > len(A))
>>> A
[1, 2]
Chi tiết phương thức remove()
>>> A = [1, 2, 3, 4, 5]
>>> A.remove(1) # xóa phần tử đầu tiên có giá trị 1
>>> A
[2, 3, 4, 5]
>>> A.remove(10) # giá trị 10 không tồn tại → LỖI
ValueError: list.remove(x): x not in list
Câu hỏi kiểm tra nhanh: Khi nào thì lệnh A.append(1) và A.insert(0, 1) có tác dụng giống nhau?
→ Khi danh sách A rỗng (A = []). Lúc đó cả hai lệnh đều cho kết quả A = [1], vì danh sách chỉ có 1 phần tử nên “đầu” và “cuối” là cùng một vị trí. Khi A không rỗng, append(1) thêm vào cuối còn insert(0, 1) chèn vào đầu → kết quả khác nhau.
Câu hỏi kiểm tra nhanh: Danh sách A trước và sau lệnh insert() là [1, 4, 10, 0] và [1, 4, 10, 5, 0]. Lệnh đã dùng là gì?
→ A.insert(3, 5) — chèn giá trị 5 vào vị trí chỉ số 3 (trước phần tử 0), đẩy phần tử 0 sang phải.
II. Phương pháp giải các dạng bài tập
Dạng 1: Xác định kết quả khi dùng toán tử in và các phương thức
Phương pháp:
- Bước 1: Viết trạng thái ban đầu của danh sách, đánh chỉ số từ 0.
- Bước 2: Thực hiện từng lệnh theo thứ tự. Với mỗi lệnh:
insert(k, x)→ chèn x tại vị trí k, đẩy phần tử k trở đi sang phải, độ dài +1.remove(x)→ tìm và xóa phần tử đầu tiên có giá trị x, độ dài −1. Nếu không tìm thấy → lỗi.clear()→ danh sách thành[].x in A→ so sánh chính xác cả giá trị và kiểu dữ liệu.
- Bước 3: Ghi nhận trạng thái danh sách sau mỗi lệnh.
Bài tập mẫu (SGK – Câu hỏi mục 2, câu 2): Danh sách A trước là [1, 4, 10, 0], sau lệnh insert() là [1, 4, 10, 5, 0]. Xác định lệnh đã dùng.
Lời giải:
So sánh hai danh sách:
| Chỉ số | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| Trước | 1 | 4 | 10 | 0 | — |
| Sau | 1 | 4 | 10 | 5 | 0 |
Số 5 được chèn vào vị trí chỉ số 3, phần tử 0 bị đẩy sang phải.
→ Lệnh: A.insert(3, 5)
Dạng 2: Chèn phần tử vào danh sách bằng insert()
Phương pháp:
- Xác định vị trí chỉ số cần chèn (nhớ chỉ số đánh từ 0).
- Lệnh
insert(k, x)sẽ chènxtrước phần tử hiện tại ở vị trík. - Sau mỗi lệnh
insert, chỉ số các phần tử phía sau đều tăng thêm 1.
Bài tập mẫu (SGK – Luyện tập, bài 1): Cho dãy A = [1, 2, 2, 3, 4, 5, 5]. Viết lệnh thực hiện:
a) Chèn số 1 vào ngay sau giá trị 1 của dãy.
Giá trị 1 đang ở chỉ số 0 → cần chèn số 1 vào chỉ số 1 (ngay sau nó):
A.insert(1, 1)
# A = [1, 1, 2, 2, 3, 4, 5, 5]
b) Chèn số 3 và số 4 vào danh sách để dãy có số 3 và số 4 liền nhau hai lần.
Hiện tại dãy là [1, 2, 2, 3, 4, 5, 5] — đã có một cặp 3, 4 ở chỉ số 3 và 4. Cần chèn thêm một cặp 3, 4 ngay bên cạnh. Chèn số 3 trước chỉ số 3 (hoặc sau chỉ số 4), rồi chèn số 4:
A.insert(5, 3) # chèn 3 sau giá trị 4
# A = [1, 2, 2, 3, 4, 3, 5, 5]
A.insert(6, 4) # chèn 4 ngay sau số 3 vừa chèn
# A = [1, 2, 2, 3, 4, 3, 4, 5, 5]
Kết quả: [1, 2, 2, 3, 4, 3, 4, 5, 5] — số 3 và số 4 liền nhau hai lần.
Dạng 3: Xóa phần tử theo điều kiện bằng vòng lặp while + remove()
Phương pháp:
Khi cần xóa phần tử khỏi danh sách trong quá trình duyệt, không dùng for (vì xóa phần tử làm thay đổi chỉ số, dễ bỏ sót). Thay vào đó dùng while với biến đếm thủ công:
i = 0
while i < len(A):
if <điều_kiện_xóa>:
A.remove(A[i]) # xóa → không tăng i (vì phần tử sau dồn lên)
else:
i = i + 1 # không xóa → mới tăng i
Tại sao chỉ tăng
ikhi không xóa? Khi xóa phần tử tại vị tríi, phần tử tiếp theo dồn vào đúng vị tríi. Nếu tăngilúc này sẽ bỏ sót phần tử vừa dồn lên.
Bài tập mẫu (SGK – Thực hành, Nhiệm vụ 2): Cho trước dãy số A. Viết chương trình xóa đi các phần tử có giá trị nhỏ hơn 0.
Lời giải:
A = [0, 1, -3, -10, 5, 9, -20, 55]
i = 0
while i < len(A):
if A[i] < 0:
A.remove(A[i])
else:
i = i + 1
print(A)
Kết quả: [0, 1, 5, 9, 55]
Mô phỏng: i=0 (A[0]=0, giữ) → i=1 (A[1]=1, giữ) → i=2 (A[2]=−3, xóa, không tăng i) → i=2 (A[2]=−10, xóa) → i=2 (A[2]=5, giữ) → i=3 (A[3]=9, giữ) → i=4 (A[4]=−20, xóa) → i=4 (A[4]=55, giữ) → i=5, kết thúc.
Dạng 4: Tìm mẫu (pattern) trong danh sách
Phương pháp:
- Dùng vòng
whileduyệt từ đầu danh sách. - Tại mỗi vị trí
i, kiểm tra xem các phần tử liên tiếpA[i], A[i+1], A[i+2]...có khớp với mẫu cần tìm không. - Dùng biến
pkq(kết quả) để ghi nhận vị trí tìm thấy. Nếu tìm thấy → dừng. Nếu không → thông báo không tìm thấy.
Bài tập mẫu (SGK – Thực hành, Nhiệm vụ 3): Cho dãy số A. Viết chương trình tìm vị trí đầu tiên mà ba số liên tiếp có giá trị là 1, 2, 3.
Lời giải:
A = [0, 4, 0, 1, 2, 3, 8, 9, 0, 1, 2, 3, 17, -16, 0, 1, 2]
p = [1, 2, 3]
pkq = -1
i = 0
while i < len(A) - 3 and pkq == -1:
if A[i] == p[0] and A[i+1] == p[1] and A[i+2] == p[2]:
pkq = i
else:
i = i + 1
if pkq >= 0:
print("Tìm thấy mẫu", p, "tại vị trí", pkq)
else:
print("Không tìm thấy mẫu", p)
Kết quả: Tìm thấy mẫu [1, 2, 3] tại vị trí 3
Giải thích: Biến pkq = -1 nghĩa là chưa tìm thấy. Vòng while chạy khi chưa tìm thấy (pkq == -1) và chưa hết danh sách. Tại i=3: A[3]=1, A[4]=2, A[5]=3 khớp mẫu → pkq = 3, vòng lặp dừng.
III. Hướng dẫn thực hành
Nhiệm vụ 1: Nhập danh sách tên học sinh, in theo thứ tự ngược
Đề bài: Nhập số n từ bàn phím, nhập danh sách n tên học sinh và in ra theo thứ tự ngược lại với thứ tự nhập.
Hướng dẫn: Do yêu cầu in ngược, ta dùng insert(0, ...) để chèn mỗi tên mới vào đầu danh sách. Khi đó tên nhập sau sẽ nằm trước, tên nhập trước sẽ bị đẩy ra sau — kết quả in ra tự nhiên là thứ tự ngược.
dsLop = []
n = int(input("Nhập số học sinh trong lớp: "))
for i in range(n):
name = input("Nhập họ tên học sinh thứ " + str(i+1) + ": ")
dsLop.insert(0, name)
print("Danh sách học sinh đã nhập:")
for name in dsLop:
print(name)
Giải thích:
dsLop.insert(0, name)— luôn chèn tên mới vào vị trí 0 (đầu danh sách), đẩy các tên đã có sang phải.- Vòng
for name in dsLopdùng toán tửinđể duyệt trực tiếp qua giá trị, in mỗi tên trên một dòng.
Ví dụ: Nhập lần lượt: An, Bình, Chi → danh sách lưu: ["Chi", "Bình", "An"] → in ra: Chi, Bình, An (ngược thứ tự nhập).
Nhiệm vụ 2: Xóa các phần tử âm khỏi danh sách
Đề bài: Cho trước dãy số A. Viết chương trình xóa đi các phần tử có giá trị nhỏ hơn 0.
Hướng dẫn: Dùng vòng while kết hợp remove(). Chú ý chỉ tăng biến đếm i khi không xóa, vì sau khi xóa phần tử phía sau dồn lên.
A = [0, 1, -3, -10, 5, 9, -20, 55]
i = 0
while i < len(A):
if A[i] < 0:
A.remove(A[i])
else:
i = i + 1
print(A)
Kết quả: [0, 1, 5, 9, 55]
Nhiệm vụ 3: Tìm mẫu [1, 2, 3] trong dãy số
Đề bài: Cho dãy số A. Tìm vị trí đầu tiên mà ba số hạng liên tiếp có giá trị là 1, 2, 3.
Hướng dẫn: Dùng biến pkq = -1 để đánh dấu chưa tìm thấy. Duyệt bằng while, kiểm tra ba phần tử liên tiếp tại mỗi vị trí, nếu khớp thì ghi nhận và dừng.
A = [0, 4, 0, 1, 2, 3, 8, 9, 0, 1, 2, 3, 17, -16, 0, 1, 2]
p = [1, 2, 3]
pkq = -1
i = 0
while i < len(A) - 3 and pkq == -1:
if A[i] == p[0] and A[i+1] == p[1] and A[i+2] == p[2]:
pkq = i
else:
i = i + 1
if pkq >= 0:
print("Tìm thấy mẫu", p, "tại vị trí", pkq)
else:
print("Không tìm thấy mẫu", p)
Kết quả: Tìm thấy mẫu [1, 2, 3] tại vị trí 3
IV. Sơ đồ tư duy
1. Toán tử in
- 1.1. Kiểm tra phần tử:
<giá_trị> in <danh_sách>→ True / False - 1.2. So sánh chính xác cả giá trị lẫn kiểu dữ liệu (1 ≠ “1”)
- 1.3. Duyệt nhanh:
for k in A:— biến k nhận trực tiếp giá trị phần tử - 1.4. Không cần
range()khi chỉ cần đọc giá trị
2. Các phương thức danh sách
- 2.1.
A.append(x)— thêm x vào cuối, độ dài +1 - 2.2.
A.insert(k, x)— chèn x tại vị trí k, đẩy phần tử sang phải, độ dài +1- k < 0 → chèn vào đầu; k > len(A) → chèn vào cuối
- 2.3.
A.remove(x)— xóa phần tử đầu tiên có giá trị x, lỗi nếu không tìm thấy - 2.4.
A.clear()— xóa toàn bộ, A thành[]
3. Kĩ thuật xóa phần tử theo điều kiện
- 3.1. Dùng
while+remove(), không dùngfor - 3.2. Chỉ tăng biến đếm khi không xóa
- 3.3. Lí do: xóa phần tử → phần tử sau dồn lên, tăng i sẽ bỏ sót
V. Sai lầm thường gặp
| Sai lầm | Đính chính |
|---|---|
1 in ["0", "1", "01", "10"] trả về True |
False. Số nguyên 1 khác xâu kí tự "1". Toán tử in so sánh chính xác cả kiểu dữ liệu. |
Dùng for để xóa phần tử theo điều kiện |
Sai. Khi xóa phần tử trong vòng for, chỉ số bị lệch dẫn đến bỏ sót phần tử. Phải dùng while và chỉ tăng biến đếm khi không xóa. |
A.remove(10) khi 10 không có trong A → không xảy ra gì |
Sai. Nếu giá trị không tồn tại, remove() sẽ báo lỗi ValueError. Cần kiểm tra bằng if x in A trước khi gọi remove(). |
A.insert(k, x) báo lỗi khi k ngoài phạm vi chỉ số |
Không lỗi. Nếu k < 0 → chèn vào đầu, nếu k > len(A) → chèn vào cuối. Đây là khác biệt quan trọng so với truy cập A[k] (sẽ lỗi nếu k ngoài phạm vi). |
append(1) và insert(0, 1) luôn cho kết quả giống nhau |
Chỉ giống khi danh sách rỗng. Khi có phần tử: append(1) thêm vào cuối, insert(0, 1) chèn vào đầu → vị trí khác nhau. |
for k in A và for i in range(len(A)) dùng thay thế nhau thoải mái |
Không hoàn toàn. for k in A chỉ đọc giá trị, không có chỉ số nên không thể thay đổi phần tử hay biết vị trí. Khi cần chỉ số (ví dụ tìm vị trí, thay đổi giá trị) → phải dùng for i in range(len(A)). |

Thầy Phạm Thành Danh
(Người kiểm duyệt, ra đề)
Chức vụ: Trưởng ban biên soạn môn Tin Học THPT
Trình độ: Cử nhân Sư phạm Tin học, Chứng chỉ hạng II, Chứng chỉ Tin học, Ngoại ngữ B1
Kinh nghiệm: 8+ năm kinh nghiệm tại Trường THPT Thuận Hóa
