Skip to main content

Buổi học 9 (25/07/2025): Vòng lặp trong Python - Nguyên tắc tự động hóa cốt lõi

Giới thiệu

Trong các buổi học trước, chúng ta đã trang bị cho chương trình khả năng lưu trữ dữ liệu (biến), xử lý thông tin (toán tử), và ra quyết định (cấu trúc if-else). Tuy nhiên, sức mạnh thực sự của máy tính nằm ở khả năng thực hiện hàng ngàn, hàng triệu thao tác một cách không mệt mỏi.

Hãy xem xét một bài toán: yêu cầu người dùng nhập vào 100 con số và tính tổng của chúng. Với kiến thức hiện tại, bạn sẽ phải viết 100 dòng input() và một biểu thức cộng 100 biến. Cách làm này không chỉ tốn công mà còn không thể mở rộng.

Trong lập trình, có một nguyên tắc quan trọng là DRY (Don't Repeat Yourself - Đừng lặp lại chính mình). Vòng lặp (Loop) chính là công cụ mạnh mẽ nhất để tuân thủ nguyên tắc này. Nó cho phép chúng ta thực thi một khối lệnh lặp đi lặp lại, tự động hóa các tác vụ nhàm chán và xây dựng những chương trình có tính linh hoạt cao.

Yêu cầu chung:


I. Vòng lặp for - Lặp với số lần xác định

Dẫn dắt & Tư duy

Hãy hình dung một người đưa thư có nhiệm vụ phát báo cho một dãy phố được đánh số từ nhà 1 đến nhà 50. Lộ trình của họ đã được xác định trước một cách rõ ràng. Vòng lặp for trong Python hoạt động với triết lý tương tự: nó được thiết kế để duyệt qua một chuỗi các phần tử đã biết trước. Bạn sử dụng for khi bạn biết chính xác điểm bắt đầu, điểm kết thúc và số lần lặp cần thực hiện.

Cú pháp:

for iterator_variable in sequence:
# Khối lệnh lặp lại
# Các lệnh này phải được thụt vào đầu dòng (indentation)

Công cụ chính: Hàm range()

Để tạo ra một dãy số tuần tự cho vòng lặp for, chúng ta thường sử dụng hàm range().

  • range(stop): Tạo một dãy số từ 0 đến stop-1.
    • Ví dụ: range(5) sẽ tạo ra dãy số: 0, 1, 2, 3, 4.
  • range(start, stop): Tạo một dãy số từ start đến stop-1.
    • Ví dụ: range(1, 6) sẽ tạo ra dãy số: 1, 2, 3, 4, 5.
  • range(start, stop, step): Tạo một dãy số từ start đến stop-1, với mỗi bước nhảy là step.
    • Ví dụ: range(2, 11, 2) sẽ tạo ra dãy số: 2, 4, 6, 8, 10.

Bài tập thực hành cho vòng lặp for

(1.1) (Mẫu) In ra bảng cửu chương

Phân tích: Bài toán yêu cầu lặp lại phép tính 7 * i với i chạy từ 1 đến 10. Đây là một tác vụ có số lần lặp xác định, vì vậy for là lựa chọn lý tưởng.

Giải pháp mẫu:

multiplication_table_of = 7
print(f"--- Bảng cửu chương {multiplication_table_of} ---")

for i in range(1, 11):
result = multiplication_table_of * i
# Sử dụng f-string để định dạng chuỗi đầu ra một cách rõ ràng
print(f"{multiplication_table_of} x {i} = {result}")

(1.2) (Thực hành) Tính giai thừa

Yêu cầu: Yêu cầu người dùng nhập một số nguyên dương n. Sau đó, tính và in ra n! (n giai thừa). Ví dụ: 5! = 1 * 2 * 3 * 4 * 5 = 120.

Gợi ý:

  1. Tương tự bài tính tổng, bạn cần một biến để tích lũy kết quả. Với phép nhân, giá trị khởi tạo nên là 1.
  2. Vòng lặp for nên chạy từ 1 đến n.

(1.3) (Thực hành) In các số chẵn trong một khoảng

Yêu cầu: In ra tất cả các số chẵn trong khoảng từ 1 đến 50.

Gợi ý:

  • Cách 1 (Hiệu quả): Sử dụng tham số step của hàm range(). range(2, 51, 2) sẽ tạo ra dãy số bắt đầu từ 2, kết thúc trước 51, và mỗi bước nhảy cách nhau 2 đơn vị.
  • Cách 2 (Luyện tư duy if trong for): Lặp qua tất cả các số từ 1 đến 50. Bên trong vòng lặp, sử dụng cấu trúc if và phép toán chia lấy dư (%) để kiểm tra xem số hiện tại có phải là số chẵn không.

Minh họa luồng đi cho Cách 2:

Giải thích luồng đi:

  • (1) Vòng lặp for bắt đầu.
  • (2) Với mỗi số (number) được lấy ra, chương trình kiểm tra điều kiện chia hết cho 2.
  • (3) Nếu điều kiện đúng, số đó được in ra. Dù đúng hay sai, luồng chương trình đều quay trở lại đầu vòng lặp để lấy số tiếp theo, cho đến khi duyệt hết dãy số thì vòng lặp kết thúc.

(1.4) (Thực hành) Đếm nguyên âm trong một chuỗi

Yêu cầu: Yêu cầu người dùng nhập vào một câu bất kỳ. Dùng vòng lặp for để duyệt qua từng ký tự của câu và đếm xem có bao nhiêu nguyên âm (a, e, i, o, u). Không phân biệt chữ hoa, chữ thường.

Gợi ý:

  1. Khởi tạo một biến vowel_count = 0.
  2. Dùng for char in user_input: để duyệt qua từng ký tự.
  3. Để không phân biệt hoa/thường, hãy chuyển ký tự về dạng chữ thường trước khi so sánh: char.lower().
  4. Dùng if để kiểm tra xem char.lower() có nằm trong chuỗi "aeiou" hay không.

II. Vòng lặp while - Lặp dựa trên điều kiện

Dẫn dắt & Tư duy

Bây giờ, hãy hình dung một người lính canh gác một pháo đài. Nhiệm vụ của anh ta không phải là "đi tuần 10 vòng rồi nghỉ", mà là "tiếp tục đi tuần cho đến khi có tín hiệu báo động". Anh ta không thể biết trước khi nào tín hiệu sẽ vang lên. Vòng lặp while hoạt động dựa trên triết lý này. Nó chỉ quan tâm đến một điều kiện: "Chừng nào điều kiện này còn đúng, thì còn tiếp tục thực thi khối lệnh".

Cú pháp:

while condition: # Chừng nào điều kiện (condition) còn đúng
# Khối lệnh lặp lại
# Bắt buộc phải có một lệnh nào đó trong khối này
# có khả năng làm cho `condition` trở thành sai (False)

Cảnh báo: Nếu không có cách nào để condition trở thành False, vòng lặp sẽ chạy mãi mãi, gây ra lỗi lặp vô tận (infinite loop).

Bài tập thực hành cho vòng lặp while

(2.1) (Mẫu) Yêu cầu nhập mật khẩu

Phân tích: Chúng ta không biết người dùng sẽ nhập sai bao nhiêu lần. Vì vậy, while là lựa chọn phù hợp. Vòng lặp sẽ tiếp tục miễn là mật khẩu nhập vào chưa chính xác.

Giải pháp mẫu:

correct_password = "python_is_awesome"
entered_password = "" # Khởi tạo chuỗi rỗng

while entered_password != correct_password:
entered_password = input("Vui lòng nhập mật khẩu: ")
if entered_password != correct_password:
print("Mật khẩu không chính xác. Vui lòng thử lại.")

print("Mật khẩu chính xác. Đăng nhập thành công!")

Minh họa luồng đi:

Giải thích luồng đi:

  • (1) Biến entered_password được khởi tạo.
  • (2) Điều kiện while được kiểm tra lần đầu. Vì giá trị ban đầu khác mật khẩu đúng, điều kiện là True.
  • (3) Chương trình đi vào trong vòng lặp, yêu cầu người dùng nhập liệu và cập nhật lại giá trị cho entered_password. Sau đó, nó quay trở lại bước 2 để kiểm tra lại điều kiện với giá trị mới.
  • (4) Quá trình này lặp lại cho đến khi người dùng nhập đúng mật khẩu. Lúc này, điều kiện ở bước 2 sẽ False, và chương trình sẽ thoát khỏi vòng lặp để thực thi lệnh cuối cùng.

(2.2) (Thực hành) Tích lũy tổng có điều kiện

Yêu cầu: Viết một chương trình liên tục yêu cầu người dùng nhập vào một số. Chương trình sẽ cộng dồn các số đó lại. Vòng lặp sẽ dừng lại khi tổng vượt quá hoặc bằng 100. Cuối cùng, in ra tổng cuối cùng đó.

Gợi ý:

  1. Khởi tạo biến total = 0.
  2. Điều kiện của vòng lặp while sẽ là total < 100.
  3. Bên trong vòng lặp, yêu cầu người dùng nhập số và cập nhật biến total.

(2.3) (Thực hành) Xác thực dữ liệu nhập (Input Validation)

Yêu cầu: Viết một chương trình yêu cầu người dùng nhập tuổi. Chương trình sẽ không chấp nhận các giá trị không hợp lệ (ví dụ: nhỏ hơn 0 hoặc lớn hơn 120). Nếu người dùng nhập sai, chương trình phải yêu cầu nhập lại cho đến khi nhận được một giá trị hợp lệ.

Gợi ý:

  1. Khởi tạo một biến age = -1 (một giá trị chắc chắn không hợp lệ để vòng lặp chạy ít nhất một lần).
  2. Điều kiện của whileage < 0 or age > 120.
  3. Bên trong vòng lặp, yêu cầu người dùng nhập tuổi và gán vào biến age.

(2.4) (Thực hành) Giảm dần đến 0

Yêu cầu: Yêu cầu người dùng nhập một số dương. Sau đó, liên tục trừ số đó đi 7 và in ra kết quả sau mỗi lần trừ. Vòng lặp dừng lại khi số đó nhỏ hơn hoặc bằng 0.

Gợi ý:

  1. Nhận số từ người dùng và lưu vào biến number.
  2. Điều kiện của whilenumber > 0.
  3. Bên trong vòng lặp, thực hiện phép trừ number = number - 7 và in number ra.

III. Điều khiển luồng vòng lặp: breakcontinue

Dẫn dắt: Đôi khi, chúng ta không muốn vòng lặp chạy một cách cứng nhắc từ đầu đến cuối. Có những lúc ta cần thoát ra giữa chừng khi đã tìm thấy thứ mình cần, hoặc bỏ qua một vài lần lặp không mong muốn. breakcontinue chính là công cụ để làm việc đó.

(3.1) Câu lệnh break - Thoát khỏi vòng lặp

break được sử dụng để chấm dứt vòng lặp ngay lập tức, bất kể điều kiện của vòng lặp còn đúng hay không.

Ví dụ: Tìm số đầu tiên chia hết cho 13 trong khoảng từ 100 đến 200.

print("Đang tìm số đầu tiên chia hết cho 13...")
for number in range(100, 201):
if number % 13 == 0:
print(f"Đã tìm thấy! Số đó là: {number}")
break # Thoát khỏi vòng lặp ngay khi tìm thấy
print("Chương trình kết thúc.")

Minh họa luồng đi:

(3.2) Câu lệnh continue - Bỏ qua lần lặp hiện tại

continue được sử dụng để bỏ qua tất cả các câu lệnh còn lại trong lần lặp hiện tại và nhảy ngay đến lần lặp tiếp theo.

Ví dụ: In ra các số từ 1 đến 10, nhưng bỏ qua các số 3 và 7.

for number in range(1, 11):
if number == 3 or number == 7:
continue # Bỏ qua lần lặp này, đi đến số tiếp theo
print(f"Số hiện tại: {number}")

Minh họa luồng đi:


IV. Các khái niệm vòng lặp nâng cao

(4.1) Vòng lặp lồng nhau (Nested Loops)

Đây là cấu trúc một vòng lặp nằm bên trong một vòng lặp khác. Vòng lặp bên trong sẽ chạy hết tất cả các lần lặp của nó cho mỗi một lần lặp của vòng lặp bên ngoài.

Ví dụ: In ra một bảng tọa độ đơn giản.

# Vòng lặp ngoài điều khiển hàng (y)
for y in range(3):
# Vòng lặp trong điều khiển cột (x)
for x in range(4):
# Dùng end=' ' để in trên cùng một dòng
print(f"({x},{y})", end=' ')
# Xuống dòng sau khi in xong một hàng
print()

(4.2) Mệnh đề else trong vòng lặp

Đây là một tính năng đặc biệt của Python. Khối lệnh else sẽ được thực thi khi vòng lặp kết thúc một cách tự nhiên (tức là không bị ngắt bởi break).

Ví dụ: Kiểm tra xem một số có phải là số nguyên tố hay không.

num_to_check = 29
# Lặp từ 2 đến căn bậc hai của số đó
for i in range(2, int(num_to_check**0.5) + 1):
if num_to_check % i == 0:
print(f"{num_to_check} không phải là số nguyên tố (chia hết cho {i}).")
break # Tìm thấy ước số, không phải số nguyên tố, thoát lặp
else:
# Vòng lặp kết thúc tự nhiên (không tìm thấy ước số nào)
print(f"{num_to_check} là số nguyên tố.")

V. (Bonus) Game đoán số có giới hạn lượt chơi

Yêu cầu: Xây dựng một trò chơi hoàn chỉnh với các quy tắc sau:

  1. Máy tính sẽ tự động nghĩ ra một số nguyên ngẫu nhiên trong khoảng từ 1 đến 100.
  2. Người chơi có tổng cộng 10 lượt để đoán ra con số đó.
  3. Sau mỗi lần đoán, máy tính sẽ phản hồi:
    • "Lớn hơn!" nếu số người chơi đoán nhỏ hơn số bí mật.
    • "Nhỏ hơn!" nếu số người chơi đoán lớn hơn số bí mật.
    • "Xin chúc mừng, bạn đã đoán đúng!" và kết thúc trò chơi nếu đoán trúng.
  4. Nếu sau 10 lượt mà người chơi vẫn chưa đoán đúng, trò chơi kết thúc và máy tính sẽ thông báo "Bạn đã thua cuộc! Con số bí mật là [số bí mật]".

Phân tích và Gợi ý tư duy:

  1. Chọn vòng lặp: Vì số lượt đoán là cố định (10 lần), vòng lặp for kết hợp với range(10) là lựa chọn phù hợp nhất.
  2. Kết thúc sớm: Làm thế nào để dừng trò chơi ngay khi người chơi đoán đúng, dù họ chưa dùng hết 10 lượt? Hãy tìm hiểu về câu lệnh break. Lệnh này cho phép "phá vỡ" và thoát khỏi vòng lặp ngay lập tức.
  3. Kiểm tra thắng/thua: Sau khi vòng lặp kết thúc, làm sao để biết người chơi thắng (do break) hay thua (do hết lượt)? Một kỹ thuật phổ biến là sử dụng một "biến cờ" (flag variable).
    • Khởi tạo một biến, ví dụ found_correctly = False trước khi bắt đầu vòng lặp.
    • Nếu người chơi đoán đúng, hãy đổi biến này thành True ngay trước khi break.
    • Sau khi vòng lặp kết thúc, chỉ cần kiểm tra giá trị của biến found_correctly. Nếu nó vẫn là False, có nghĩa là người chơi đã thua.

Minh họa luồng đi:

Mục tiêu kiến thức: Bài tập này giúp củng cố kỹ năng tổng hợp:

  • Sử dụng thư viện random.
  • Tổ chức chương trình với vòng lặp for có số lần xác định.
  • Lồng ghép cấu trúc if-elif-else phức tạp bên trong vòng lặp.
  • Sử dụng lệnh break để điều khiển luồng của vòng lặp.
  • Áp dụng kỹ thuật "biến cờ" để xử lý logic sau khi vòng lặp kết thúc.

VI. Tổng kết & Tư duy lựa chọn

Kỹ năng cốt lõi không phải là ghi nhớ cú pháp, mà là khả năng phân tích vấn đề để lựa chọn đúng công cụ.

  • Khi nào dùng for? Khi số lần lặp được xác định trước (Lặp qua mỗi tháng trong năm, lặp 10 lần...).
  • Khi nào dùng while? Khi số lần lặp không xác định trước và phụ thuộc vào một điều kiện (Lặp cho đến khi người dùng nhập 'thoát', lặp trong khi máu nhân vật > 0...).

Việc thành thạo vòng lặp sẽ mở ra cánh cửa để bạn giải quyết những bài toán phức tạp và thú vị hơn rất nhiều. Hãy kiên trì thực hành.


VII. Gợi ý Prompt cho AI (Ngắn gọn, xúc tích)

Để hiểu khái niệm:

"Giải thích vòng lặp for trong Python cho người mới bắt đầu. Dùng ví dụ duyệt qua một dãy số. So sánh ưu nhược điểm của nó với vòng lặp while."

Để gỡ lỗi:

"Đoạn code Python này gây ra lỗi lặp vô tận. Giải thích tại sao và cách khắc phục. [Dán đoạn code của bạn vào đây]"

Để tìm phương pháp:

"Tôi muốn viết chương trình yêu cầu người dùng nhập một chuỗi cho đến khi họ nhập 'exit'. Nên dùng vòng lặp for hay while? Cung cấp một đoạn code mẫu."

Để tối ưu hóa:

"Đây là code của tôi để tìm các số nguyên tố dưới 100. Có cách nào dùng vòng lặp để viết code này hiệu quả hơn không? [Dán đoạn code của bạn vào đây]"