Bài 22: Kiểu dữ liệu danh sách – Lý thuyết | Tin học 10

I. Lý thuyết trọng tâm

1. Kiểu dữ liệu danh sách (list)

a) Tại sao cần kiểu danh sách?

Các kiểu dữ liệu cơ bản (số nguyên, số thực, xâu kí tự, logic) chỉ lưu được một giá trị duy nhất. Khi cần lưu một dãy nhiều giá trị — ví dụ danh sách điểm của cả lớp, dãy tên học sinh — ta cần kiểu dữ liệu danh sách (còn gọi là dãy hay mảng). Trong Python, kiểu danh sách phổ biến nhất là list.

b) Khởi tạo danh sách

Cú pháp:

<tên_list> = [<giá_trị_1>, <giá_trị_2>, ..., <giá_trị_n>]

Ví dụ:

A = [1, 2, 3, 4, 5]           # list gồm 5 số nguyên
B = [1.5, 2, "Python", "List", 0]   # list hỗn hợp nhiều kiểu
C = []                          # list rỗng (độ dài 0)

Đặc điểm quan trọng: Khác với mảng trong nhiều ngôn ngữ lập trình khác, list của Python cho phép các phần tử có kiểu dữ liệu khác nhau (số nguyên, số thực, xâu kí tự… chung một danh sách).

c) Truy cập phần tử qua chỉ số

Mỗi phần tử trong list được đánh chỉ số bắt đầu từ 0. Truy cập phần tử bằng cú pháp:

<danh_sách>[<chỉ_số>]

Với danh sách có n phần tử, chỉ số hợp lệ chạy từ 0 đến n − 1 (tức len() − 1).

Phần tử A[0] A[1] A[2] A[3] A[4]
Giá trị 1 2 3 4 5
Chỉ số 0 1 2 3 4

⚠️ Nếu truy cập chỉ số ngoài phạm vi (ví dụ A[len(A)] tức A[5] khi danh sách chỉ có 5 phần tử) → lỗi IndexError.

Câu hỏi kiểm tra nhanh: Cho A = [1, 0, "One", 9, 15, "Two", True, False]. Giá trị A[0], A[2], A[7], A[len(A)] lần lượt là gì?

A[0] = 1, A[2] = “One”, A[7] = False, A[len(A)] = A[8]Lỗi (chỉ số hợp lệ chỉ từ 0 đến 7).

d) Các thao tác cơ bản trên list

Thao tác Cú pháp Ví dụ Kết quả
Đo độ dài len(<list>) len([1,2,3,4,5]) 5
Thay đổi giá trị <list>[i] = <giá_trị_mới> A[1] = "One" A thành [1, "One", 3, 4, 5]
Xóa phần tử del <list>[i] del A[4] A thành [1, "One", 3, 4]
Ghép hai danh sách <list1> + <list2> [1,2] + [3,4,5,6] [1, 2, 3, 4, 5, 6]
Tạo list rỗng a = [] len(a) 0

Câu hỏi kiểm tra nhanh: Giả sử A là một danh sách các số. Mỗi lệnh sau thực hiện gì?

  • A = A + [10]Ghép thêm phần tử 10 vào cuối danh sách A.
  • del A[0]Xóa phần tử đầu tiên của A (các phần tử phía sau dồn lên).
  • A = [100] + AChèn số 100 vào đầu danh sách A.
  • A = A[1] * 25 → Lấy giá trị phần tử thứ 2 nhân với 25, gán kết quả (một số) cho A. Sau lệnh này A không còn là list mà trở thành một số.

2. Duyệt các phần tử của danh sách

Để xử lí lần lượt từng phần tử trong danh sách, ta sử dụng vòng lặp for kết hợp với range().

a) Duyệt toàn bộ danh sách

for i in range(len(A)):
    print(A[i], end=" ")

Biến i lần lượt nhận giá trị từ 0 đến len(A) − 1, tức duyệt qua tất cả chỉ số hợp lệ.

b) Duyệt một phần danh sách

A = [3, 2, 1, 5, 6, 10, 7, 12, 18]
for i in range(2, 5):
    print(A[i], end=" ")

Kết quả: 1 5 6 — chỉ duyệt các phần tử có chỉ số 2, 3, 4.

c) Các mẫu duyệt thường gặp

Mục đích Mẫu code
Tính tổng các phần tử thỏa điều kiện S = 0for i in range(len(A)): if <điều_kiện>: S = S + A[i]
Đếm số phần tử thỏa điều kiện C = 0for i in range(len(A)): if <điều_kiện>: C = C + 1
In ra các phần tử thỏa điều kiện for i in range(len(A)): if <điều_kiện>: print(A[i])

Câu hỏi kiểm tra nhanh: Đoạn code sau thực hiện gì?

S = 0
for i in range(len(A)):
    if A[i] > 0:
        S = S + A[i]
print(S)

→ Tính tổng các phần tử dương (lớn hơn 0) trong danh sách A.

C = 0
for i in range(len(A)):
    if A[i] > 0:
        C = C + 1
print(C)

Đếm số lượng phần tử dương trong danh sách A.

3. Thêm phần tử vào danh sách bằng phương thức append()

Python cung cấp các lệnh đặc biệt gọi là phương thức (method), được thiết kế riêng cho kiểu list.

Cú pháp chung: <danh_sách>.<phương_thức>()

Phương thức append() — thêm một phần tử vào cuối danh sách:

A = [1, 2]
A.append(10)
# A trở thành [1, 2, 10]

Sau khi gọi append(), độ dài danh sách tăng thêm 1.

Lưu ý cú pháp: Viết tên biến danh sách, dấu chấm ., rồi đến append(<giá_trị>).

Câu hỏi kiểm tra nhanh: Danh sách A sẽ như thế nào sau các lệnh sau?

A = [2, 4, 10, 1, 0]
A.append(100)
del A[1]

→ Sau append(100): A = [2, 4, 10, 1, 0, 100] (thêm 100 vào cuối). → Sau del A[1]: A = [2, 10, 1, 0, 100] (xóa phần tử chỉ số 1, tức số 4).

II. Hướng dẫn thực hành

Nhiệm vụ 1: Nhập và in danh sách tên học sinh

Đề bài: Nhập số n từ bàn phím, sau đó nhập danh sách n tên các bạn trong lớp và in ra danh sách các tên đó, mỗi tên trên một dòng.

Hướng dẫn: Tạo list rỗng, nhập số lượng n, dùng vòng for kết hợp input()append() để đưa dần từng tên vào danh sách. Vì range(n) bắt đầu từ 0, trong thông báo nhập cần viết str(i+1) để số thứ tự hiển thị từ 1.

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.append(name)
print("Danh sách học sinh đã nhập:")
for i in range(len(dsLop)):
    print(dsLop[i])

Giải thích từng bước:

  • dsLop = [] — khởi tạo danh sách rỗng.
  • Vòng for đầu tiên: lặp n lần, mỗi lần nhập một tên bằng input() rồi thêm vào cuối danh sách bằng append().
  • Vòng for thứ hai: duyệt và in từng tên, mỗi tên trên một dòng (mặc định print() xuống dòng).

Nhiệm vụ 2: Nhập dãy số, tính tổng và trung bình

Đề bài: Nhập một dãy số từ bàn phím. Tính tổng, trung bình của dãy và in dãy số trên một hàng ngang.

Hướng dẫn: Tương tự Nhiệm vụ 1, khác ở chỗ nhập số nguyên nên cần dùng int() để chuyển đổi dữ liệu. Đồng thời cộng dồn vào biến tổng T ngay khi nhập.

A = []
T = 0
n = int(input("Nhập số tự nhiên n: "))
for i in range(n):
    num = int(input("Nhập số thứ " + str(i+1) + ": "))
    A.append(num)
    T = T + num
print("Dãy số đã nhập:")
for i in range(n):
    print(A[i], end=" ")
print()
print("Tổng:", T)
print("Trung bình:", T/n)

Giải thích từng bước:

  • A = [], T = 0 — khởi tạo danh sách rỗng và biến tổng bằng 0.
  • Vòng for nhập: mỗi lần nhập một số nguyên (int(input(...))), đưa vào list bằng append(), đồng thời cộng dồn vào T.
  • In dãy trên hàng ngang: dùng end=" " để các số cách nhau bởi dấu cách thay vì xuống dòng.
  • Trung bình = T/n (tổng chia số phần tử).

III. Phương pháp giải các dạng bài tập

Dạng 1: Xác định kết quả các thao tác trên danh sách

Phương pháp:

Thực hiện mô phỏng từng bước (chạy tay) theo trình tự:

  • Bước 1: Viết ra 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 đúng thứ tự, cập nhật lại danh sách sau mỗi lệnh.
  • Bước 3: Chú ý các trường hợp đặc biệt: chỉ số ngoài phạm vi (gây lỗi), phép * biến list thành số, phép + ghép hai list.

Bảng tra nhanh:

Lệnh Tác dụng Độ dài sau lệnh
A[i] = x Thay giá trị phần tử chỉ số i Không đổi
del A[i] Xóa phần tử chỉ số i Giảm 1
A.append(x) Thêm x vào cuối Tăng 1
A = A + [x] Ghép [x] vào cuối A Tăng 1
A = [x] + A Ghép [x] vào đầu A Tăng 1
A[len(A)] Lỗi IndexError

Bài tập mẫu (SGK – Câu hỏi mục 3, câu 2): Danh sách A sẽ như thế nào sau các lệnh?

A = [2, 4, 10, 1, 0]
A.append(100)
del A[1]

Lời giải:

Bước Lệnh Trạng thái A
0 Khởi tạo [2, 4, 10, 1, 0] — chỉ số 0→4
1 A.append(100) [2, 4, 10, 1, 0, 100] — thêm 100 vào cuối
2 del A[1] [2, 10, 1, 0, 100] — xóa phần tử chỉ số 1 (giá trị 4)

Kết quả: A = [2, 10, 1, 0, 100]

Dạng 2: Duyệt danh sách — tính tổng, đếm, lọc phần tử

Phương pháp:

Sử dụng vòng lặp for kết hợp range(len(A)) để duyệt qua từng phần tử. Tùy yêu cầu mà áp dụng mẫu phù hợp:

Yêu cầu Khởi tạo biến Thân vòng lặp
Tính tổng phần tử thỏa ĐK S = 0 if <ĐK>: S = S + A[i]
Đếm phần tử thỏa ĐK C = 0 if <ĐK>: C = C + 1
In phần tử thỏa ĐK if <ĐK>: print(A[i])

Một số điều kiện hay gặp: A[i] > 0 (dương), A[i] % 2 == 0 (chẵn), A[i] % 2 != 0 (lẻ), A[i] < 0 (âm).

Bài tập mẫu (SGK – Câu hỏi mục 2, câu 2): Cho dãy các số nguyên A, viết chương trình in ra các số chẵn của A.

Lời giải:

A = [3, 7, 2, 8, 5, 10, 1, 6]   # ví dụ dãy A cho trước
for i in range(len(A)):
    if A[i] % 2 == 0:
        print(A[i], end=" ")

Kết quả: 2 8 10 6

Giải thích: Duyệt từng phần tử, kiểm tra điều kiện chia hết cho 2 (A[i] % 2 == 0), nếu đúng thì in ra.

Dạng 3: Viết chương trình nhập và xử lí danh sách

Phương pháp:

Quy trình chuẩn gồm 3 bước:

  • Bước 1 – Khởi tạo: Tạo danh sách rỗng, nhập số lượng phần tử n.
  • Bước 2 – Nhập dữ liệu: Dùng vòng for kết hợp input()append() để thêm từng phần tử.
  • Bước 3 – Xử lí và xuất: Duyệt danh sách, tính toán theo yêu cầu, in kết quả.

Lưu ý quan trọng:

  • Nếu nhập xâu kí tự (tên): dùng trực tiếp input().
  • Nếu nhập số nguyên: bọc int(input(...)).
  • range(n) bắt đầu từ 0, nên thông báo nhập nên viết str(i+1) để hiển thị số thứ tự từ 1.

Bài tập mẫu (SGK – Thực hành, Nhiệm vụ 2): Nhập một dãy số từ bàn phím. Tính tổng, trung bình của dãy và in dãy số trên một hàng ngang.

Lời giải:

A = []
T = 0
n = int(input("Nhập số tự nhiên n: "))
for i in range(n):
    num = int(input("Nhập số thứ " + str(i+1) + ": "))
    A.append(num)
    T = T + num
print("Dãy số đã nhập:")
for i in range(n):
    print(A[i], end=" ")
print()
print("Tổng:", T)
print("Trung bình:", T/n)

Giải thích: Khởi tạo list rỗng A và biến tổng T = 0. Mỗi lần nhập một số, vừa đưa vào danh sách bằng append() vừa cộng dồn vào T. Cuối cùng in dãy trên hàng ngang (dùng end=" "), tổng và trung bình (T/n).

Dạng 4: Xóa phần tử và thêm phần tử vào đầu danh sách

Phương pháp:

Yêu cầu Cách thực hiện
Xóa phần tử cuối cùng del A[len(A) - 1]
Thêm phần tử vào đầu A = [<giá_trị>] + A
Thêm phần tử vào cuối A.append(<giá_trị>) hoặc A = A + [<giá_trị>]

Bài tập mẫu (SGK – Luyện tập, bài 1 & 2):

Bài 1: Viết lệnh xóa phần tử cuối cùng của danh sách A bằng lệnh del.

del A[len(A) - 1]

Giải thích: Phần tử cuối cùng có chỉ số len(A) - 1 (vì chỉ số đánh từ 0).

Bài 2: Có thể thêm một phần tử vào đầu danh sách được không?

Có. Dùng phép ghép danh sách:

A = [<giá_trị_mới>] + A

Ví dụ: A = [100] + A sẽ chèn số 100 vào vị trí đầu tiên của A.

Dạng 5: Tìm giá trị lớn nhất (nhỏ nhất) và chỉ số của nó

Phương pháp:

  • Bước 1: Giả sử phần tử đầu tiên (A[0]) là lớn nhất (hoặc nhỏ nhất). Gán biến max_val = A[0], max_idx = 0.
  • Bước 2: Duyệt từ phần tử thứ 2 đến cuối. Nếu gặp phần tử lớn hơn (hoặc nhỏ hơn) giá trị hiện tại thì cập nhật cả giá trị và chỉ số.
  • Bước 3: In kết quả.

Bài tập mẫu (SGK – Vận dụng): Cho dãy số A. Viết chương trình tìm giá trị và chỉ số của phần tử lớn nhất.

Lời giải:

A = [3, 7, 2, 9, 5, 1]   # ví dụ
max_val = A[0]
max_idx = 0
for i in range(1, len(A)):
    if A[i] > max_val:
        max_val = A[i]
        max_idx = i
print("Giá trị lớn nhất:", max_val)
print("Chỉ số:", max_idx)

Kết quả: Giá trị lớn nhất: 9, Chỉ số: 3.

Tương tự cho tìm nhỏ nhất: Chỉ cần đổi điều kiện A[i] > max_val thành A[i] < min_val.

IV. Sơ đồ tư duy

1. Kiểu dữ liệu danh sách (list)

  • 1.1. Khởi tạo: A = [v1, v2, ..., vn], list rỗng: A = []
  • 1.2. Các phần tử có thể có kiểu dữ liệu khác nhau
  • 1.3. Chỉ số: từ 0 đến len(A) - 1
  • 1.4. Truy cập: A[i]; thay đổi: A[i] = x
  • 1.5. Xóa: del A[i]; ghép: A + B; độ dài: len(A)

2. Duyệt danh sách bằng for

  • 2.1. Duyệt toàn bộ: for i in range(len(A))
  • 2.2. Duyệt một phần: for i in range(a, b)
  • 2.3. Mẫu: tính tổng (S += A[i]), đếm (C += 1), lọc (if ... print)

3. Thêm phần tử – phương thức append()

  • 3.1. Cú pháp: A.append(x) — thêm x vào cuối
  • 3.2. Sau append: độ dài tăng 1
  • 3.3. Thêm vào đầu: A = [x] + A

4. Thực hành

  • 4.1. Nhập danh sách: tạo list rỗng → vòng for → input() + append()
  • 4.2. Nhập số: bọc int(input(...)); nhập xâu: input() trực tiếp
  • 4.3. Tính tổng, trung bình, tìm max/min

V. Sai lầm thường gặp

Sai lầm Đính chính
Chỉ số list bắt đầu từ 1 Chỉ số bắt đầu từ 0. Phần tử đầu tiên là A[0], phần tử cuối là A[len(A)-1].
Truy cập A[len(A)] để lấy phần tử cuối A[len(A)] gây lỗi IndexError vì chỉ số hợp lệ cao nhất là len(A) - 1. Phần tử cuối cùng truy cập bằng A[len(A) - 1].
Sau del A[i], các phần tử phía sau giữ nguyên chỉ số Sau khi xóa, các phần tử phía sau dồn lên, chỉ số thay đổi. Ví dụ: A = [2,4,10], sau del A[0]A = [4,10], lúc này A[0] = 4 (không phải 4 ở chỉ số 1 như trước).
A = A + 10 để thêm số 10 vào list Phải ghép list với list: A = A + [10] (đặt 10 trong ngoặc vuông). Hoặc dùng A.append(10).
A.append([10])A.append(10) là như nhau Khác nhau: A.append(10) thêm số 10 vào cuối. A.append([10]) thêm một list [10] làm phần tử cuối → tạo list lồng nhau.
Lệnh A = A[1] * 25 vẫn giữ A là list Sai. A[1] lấy ra một giá trị (số), nhân với 25 cho kết quả là một số, gán lại cho A → A không còn là list nữa.
Thầy Phạm Thành Danh

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