Giải bài tập SGK: Bài 23: Một số lệnh làm việc với dữ liệu danh sách – Tin học 10

Mục lục [Ẩn]

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 đó

Câu hỏi mở đầu trang 115

Câu hỏi mở đầu

Đề bài: Trong bài trước chúng ta đã biết cách dùng lệnh append để thêm phần tử vào cuối một danh sách. Vậy Python có lệnh nào dùng để:

  • Xoá nhanh một danh sách?
  • Chèn thêm phần tử vào đầu hay giữa danh sách?
  • Kiểm tra một phần tử có nằm trong một danh sách không?

Lời giải:

Python có các lệnh tương ứng với từng yêu cầu:

Yêu cầu Lệnh trong Python
Xoá nhanh toàn bộ một danh sách A.clear()
Chèn thêm phần tử vào đầu hay giữa danh sách A.insert(k, x)
Kiểm tra một phần tử có nằm trong danh sách không Dùng toán tử in: <giá trị> in <danh sách>

1. Duyệt danh sách với toán tử in

Câu hỏi củng cố mục 1 trang 116

Đề bài:

1. Giả sử $A = [\text{“0”}, \text{“1”}, \text{“01”}, \text{“10”}]$. Các biểu thức sau trả về giá trị đúng hay sai?

a) 1 in A b) "01" in A

Lời giải:

Chú ý: Các phần tử trong $A$ đều là xâu kí tự (có dấu nháy kép), không phải số.

Câu a) 1 in A:

  • Số $1$ là số nguyên, trong khi $A$ chỉ chứa các xâu kí tự "0", "1", "01", "10".
  • Số nguyên $1$ khác xâu "1" (kiểu dữ liệu khác nhau).

→ Kết quả: False (Sai).

Câu b) "01" in A:

  • Xâu "01" có trong $A$ (là phần tử thứ ba).

→ Kết quả: True (Đúng).

2. Hãy giải thích ý nghĩa từ khoá in trong câu lệnh sau:

for i in range(10):
    <các lệnh>

Lời giải:

Trong câu lệnh for i in range(10):, từ khoá in có nghĩa là biến $i$ sẽ lần lượt nhận các giá trị trong vùng giá trị do range(10) tạo ra (tức là $0, 1, 2, …, 9$).

→ Mỗi lần $i$ nhận một giá trị mới, <các lệnh> được thực hiện một lần, tổng cộng vòng lặp chạy $10$ lần.

2. Một số lệnh làm việc với danh sách

Câu hỏi củng cố mục 2 trang 117

Đề bài:

1. Khi nào thì lệnh A.append(1)A.insert(0, 1) có tác dụng giống nhau?

Lời giải:

  • A.append(1): thêm số $1$ vào cuối danh sách $A$.
  • A.insert(0, 1): chèn số $1$ vào vị trí $0$ (đầu) của danh sách $A$.

→ Hai lệnh này có tác dụng giống nhau khi danh sách $A$ rỗng (vì khi đó “đầu” và “cuối” trùng nhau, đều cho kết quả $A = [1]$).

2. 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ì?

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 chỉ số $3$ (đẩy số $0$ về chỉ số $4$).

→ Lệnh đã dùng: A.insert(3, 5).

Thực hành trang 117 – 118

Nhiệm vụ 1 trang 117

Đề bài: Nhập số $n$ từ bàn phím, sau đó nhập danh sách $n$ tên học sinh trong lớp và in ra danh sách học sinh này, mỗi tên trên một dòng. Yêu cầu danh sách được in ra theo thứ tự ngược lại với thứ tự đã nhập.

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

Ý tưởng:

  • Sau mỗi lần nhập tên, dùng insert(0, name) để chèn tên đó vào đầu danh sách.
  • Như vậy tên nhập sau cùng sẽ ở đầu, tên nhập đầu tiên sẽ ở cuối → ngược thứ tự.

Em mở chế độ soạn thảo (File / New File) và gõ:

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)

Ví dụ khi chạy (nhập $n = 3$, các tên An, Bình, Cường):

Nhập số học sinh trong lớp: 3
Nhập họ tên học sinh thứ 1: An
Nhập họ tên học sinh thứ 2: Bình
Nhập họ tên học sinh thứ 3: Cường
Danh sách học sinh đã nhập:
Cường
Bình
An

Chú ý: Ở vòng for thứ hai, em dùng cú pháp for name in dsLop (dùng toán tử in) để duyệt danh sách mà không cần range(len(...)).

Nhiệm vụ 2 trang 117

Đề bài: Cho trước dãy số $A$. Viết chương trình xoá đi các phần tử có giá trị nhỏ hơn $0$ từ $A$.

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

Ý tưởng:

  • Dùng vòng while để duyệt từng phần tử (không dùng for vì danh sách bị thay đổi khi xoá).
  • Nếu $A[i] < 0$ thì xoá bằng A.remove(A[i]) (sau khi xoá thì không tăng $i$, vì phần tử bên phải đã dồn lên).
  • Nếu $A[i] \geq 0$ thì tăng $i$.

Chương trình:

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ả khi chạy:

[0, 1, 5, 9, 55]

Chú ý quan trọng: Khi gặp phần tử âm, xoá xong không tăng $i$. Vì sau khi xoá, các phần tử phía sau đã dịch lên trước, nên phần tử mới tại vị trí $i$ chưa được kiểm tra.

Nhiệm vụ 3 trang 118

Đề bài: Cho trước dãy số $A$. Viết chương trình tìm và chỉ ra vị trí đầu tiên của dãy số $A$ mà ba số hạng liên tiếp có giá trị là $1, 2, 3$. Nếu tìm thấy thì thông báo vị trí tìm thấy, nếu không thì thông báo "Không tìm thấy mẫu".

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

Ý tưởng:

  • Tạo mẫu $p = [1, 2, 3]$.
  • Duyệt $i$ từ $0$ đến $len(A) – 3$. Tại mỗi vị trí $i$, kiểm tra xem $A[i], A[i+1], A[i+2]$ có bằng $p[0], p[1], p[2]$ hay không.
  • Dùng biến pkq (vị trí kết quả) lưu vị trí tìm được, khởi tạo $= -1$.
  • Khi tìm thấy thì dừng vòng lặp (bằng điều kiện pkq == -1 trong while).

Chương trình:

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ả khi chạy (với dãy A ở trên):

Tìm thấy mẫu  [1, 2, 3]  tại vị trí 3

Chú ý: Điều kiện vòng lặp i < len(A) - 3 để đảm bảo có đủ $3$ phần tử $A[i], A[i+1], A[i+2]$ để so sánh.

Luyện tập trang 118

Luyện tập 1 trang 118

Đề bài: Cho dãy số $[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.

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.

Lời giải:

Câu a:

  • Giá trị $1$ ở chỉ số $0$. “Ngay sau” tức là chèn vào chỉ số $1$.

→ Lệnh:

A.insert(1, 1)

Kết quả: $A = [1, 1, 2, 2, 3, 4, 5, 5]$.

Câu b:

  • Dãy gốc: $A = [1, 2, 2, 3, 4, 5, 5]$. Số $3$ ở chỉ số $3$, số $4$ ở chỉ số $4$ → đã có cặp $(3, 4)$ liền nhau một lần.
  • Cần chèn thêm một cặp $(3, 4)$ nữa để có “liền nhau hai lần”.
  • Cách làm: chèn số $3$ vào chỉ số $5$ (ngay sau cặp $3, 4$ đầu), rồi chèn số $4$ vào chỉ số $6$.

→ Lệnh:

A.insert(5, 3)
A.insert(6, 4)

Kết quả: $A = [1, 2, 2, 3, 4, 3, 4, 5, 5]$ → có cặp $(3, 4)$ ở vị trí $(3, 4)$ và $(5, 6)$ ✓.

Luyện tập 2 trang 118

Đề bài: Cho trước dãy số $A$. Viết chương trình thực hiện công việc sau:

  • Xoá đi một phần tử ở chính giữa dãy nếu số phần tử của dãy là số lẻ.
  • Xoá đi hai phần tử ở chính giữa của dãy nếu số phần tử của dãy là số chẵn.

Lời giải:

Phân tích vị trí chính giữa: Gọi $n = len(A)$.

  • Nếu $n$ lẻ: phần tử giữa ở chỉ số $n // 2$.Ví dụ $n = 5$: các chỉ số $0, 1, 2, 3, 4$ → phần tử giữa ở chỉ số $2 = 5 // 2$.
  • Nếu $n$ chẵn: hai phần tử giữa ở chỉ số $n // 2 – 1$ và $n // 2$.Ví dụ $n = 6$: các chỉ số $0, 1, 2, 3, 4, 5$ → hai phần tử giữa ở chỉ số $2$ và $3$.

Chương trình:

n = len(A)
if n%2 == 1:
    del A[n//2]
else:
    del A[n//2]
    del A[n//2 - 1]
print(A)

Chú ý: Khi $n$ chẵn, em xoá A[n//2] trước, sau đó xoá A[n//2 - 1]. Lý do: khi xoá A[n//2] thì phần tử bên trái (A[n//2 - 1]) vẫn giữ nguyên chỉ số, nên xoá tiếp được.

Ví dụ:

  • $A = [1, 2, 3, 4, 5]$ ($n = 5$ lẻ) → xoá $A[2] = 3$ → $A = [1, 2, 4, 5]$.
  • $A = [1, 2, 3, 4, 5, 6]$ ($n = 6$ chẵn) → xoá $A[3] = 4$, rồi xoá $A[2] = 3$ → $A = [1, 2, 5, 6]$.

Vận dụng trang 118

Vận dụng 1 trang 118

Đề bài: Viết chương trình nhập $n$ từ bàn phím, tạo và in ra màn hình dãy số $A$ bao gồm $n$ số tự nhiên chẵn đầu tiên.

Lời giải:

Ý tưởng:

  • $n$ số chẵn đầu tiên là: $2, 4, 6, …, 2n$.
  • Dùng vòng for với $i$ chạy từ $1$ đến $n$, mỗi lần thêm $2 \times i$ vào danh sách.

Chương trình:

n = int(input("Nhập n: "))
A = []
for i in range(1, n+1):
    A.append(2*i)
print("Dãy số chẵn:", A)

Ví dụ khi chạy (nhập $n = 5$):

Nhập n: 5
Dãy số chẵn: [2, 4, 6, 8, 10]

Vận dụng 2 trang 118

Đề bài: Dãy số Fibonacci được xác định như sau:

$$F_0 = 0, \quad F_1 = 1, \quad F_n = F_{n-1} + F_{n-2} \text{ (với } n \geq 2)$$

Viết chương trình nhập $n$ từ bàn phím, tạo và in ra màn hình dãy số $A$ bao gồm $n$ số hạng đầu của dãy Fibonacci.

Lời giải:

Ý tưởng:

  • Khởi tạo danh sách $A = [0, 1]$ (hai số hạng đầu $F_0, F_1$).
  • Dùng vòng for với $i$ chạy từ $2$ đến $n – 1$, mỗi lần thêm $A[i-1] + A[i-2]$ vào danh sách.

Chương trình:

n = int(input("Nhập n: "))
A = [0, 1]
for i in range(2, n):
    A.append(A[i-1] + A[i-2])
print("Dãy Fibonacci:", A)

Ví dụ khi chạy (nhập $n = 8$):

Nhập n: 8
Dãy Fibonacci: [0, 1, 1, 2, 3, 5, 8, 13]

Kiểm tra:

  • $F_0 = 0, F_1 = 1$.
  • $F_2 = F_1 + F_0 = 1 + 0 = 1$.
  • $F_3 = F_2 + F_1 = 1 + 1 = 2$.
  • $F_4 = F_3 + F_2 = 2 + 1 = 3$. ✓

Chú ý: Chương trình này áp dụng cho $n \geq 2$. Nếu $n = 1$, em chỉ cần in $A = [0]$.

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