Danh sách bài viết

Bài 9: Vòng lặp while và break / continue

Vòng lặp while trong Python: cú pháp, khi nào dùng thay cho for, bẫy infinite loop, break / continue, while True, while ... else, và pattern retry với exponential backoff cho AI Engineer.

24/05/2026
10 phút đọc
0 lượt xem
1

Mục tiêu bài học

Sau bài này bạn sẽ:

  • Viết được vòng lặp while với điều kiện dừng đúng.
  • Biết khi nào nên dùng while thay vì for.
  • Tránh được bẫy infinite loop và biết cách dừng tiến trình đang treo.
  • Dùng break để thoát loop, continue để bỏ qua iteration.
  • Biết pattern while True + break và mệnh đề while ... else.
  • Áp dụng while vào pattern retry với exponential backoff khi gọi API model.
2

Cú pháp while

while lặp lại khối lệnh khi điều kiện còn True. Trước mỗi lần lặp, Python kiểm tra lại điều kiện; khi điều kiện thành False thì thoát loop.

while <condition>:
    <body>

Ví dụ đếm từ 1 đến 5:

i = 1
while i <= 5:
    print(i)
    i += 1     # cập nhật biến điều kiện
# 1
# 2
# 3
# 4
# 5

Ba phần luôn cần có khi viết while:

  • Khởi tạo biến điều kiện trước loop (i = 1).
  • Điều kiện kiểm tra ở đầu mỗi lần lặp (i <= 5).
  • Cập nhật biến điều kiện trong body (i += 1) — thiếu bước này là dính infinite loop.
3

Khi nào dùng while thay vì for

Dùng for khi biết trước số lần lặp hoặc đang duyệt một iterable (list, range, file, ...). Dùng while khi số lần lặp phụ thuộc điều kiện động mà bạn không biết trước.

Các tình huống điển hình của while:

  • Đọc input từ người dùng đến khi họ gõ "quit".
  • Retry một network call cho đến khi success hoặc hết quota.
  • Lặp huấn luyện đến khi loss nhỏ hơn ngưỡng (early stopping theo điều kiện).
  • Đọc dữ liệu streaming đến khi nguồn đóng.
command = ""
while command != "quit":
    command = input("> ")
    print(f"Bạn vừa gõ: {command}")

Đoạn này không thể viết bằng for đơn giản, vì số lần lặp phụ thuộc người dùng.

4

Bẫy infinite loop và cách dừng

Lỗi phổ biến nhất với whilequên cập nhật biến điều kiện, khiến điều kiện luôn True:

# SAI — vòng lặp vô hạn, không bao giờ thoát
i = 1
while i <= 5:
    print(i)
    # thiếu i += 1

Cách dừng một loop đang treo:

  • Terminal (python file.py): nhấn Ctrl + C để gửi tín hiệu KeyboardInterrupt.
  • Google Colab / Jupyter: bấm nút Stop (hình vuông) bên trái cell, hoặc menu Runtime → Interrupt execution.
  • VS Code Notebook: nút Interrupt trên thanh cell.

Một biến thể tinh vi hơn: điều kiện về mặt logic không bao giờ False vì kiểu dữ liệu sai:

n = "5"               # n là str, không phải int!
while n > 0:          # so sánh str với int -> TypeError trong Python 3
    print(n)
    n -= 1

Trước khi chạy while trên dữ liệu ngoài, kiểm tra kiểu bằng type() hoặc convert tường minh.

5

break — thoát vòng lặp

break thoát ngay lập tức khỏi vòng lặp gần nhất, không kiểm tra lại điều kiện.

i = 1
while i <= 10:
    if i == 4:
        break          # dừng khi i = 4
    print(i)
    i += 1
# 1
# 2
# 3

break chỉ thoát loop chứa nó trực tiếp. Nếu lồng nhiều loop, mỗi lần break chỉ thoát một cấp.

6

continue — bỏ qua iteration

continue bỏ qua phần còn lại của iteration hiện tại, quay về kiểm tra điều kiện cho lần lặp kế tiếp.

# In các số lẻ từ 1 đến 10
i = 0
while i < 10:
    i += 1
    if i % 2 == 0:
        continue       # nếu chẵn, bỏ qua print
    print(i)
# 1 3 5 7 9

Lưu ý đặt i += 1 trước continue; nếu đặt sau, khi gặp số chẵn loop sẽ không tăng i và treo vô hạn.

7

while True + break

Khi điều kiện thoát nằm ở giữa loop chứ không ở đầu, pattern phổ biến là while True + break:

while True:
    command = input("Nhập lệnh (quit để thoát): ")
    if command == "quit":
        break
    print(f"Đang chạy: {command}")

Cách này tránh phải khởi tạo command trước loop chỉ để vượt qua điều kiện ở đầu, code đọc thẳng hơn so với:

command = ""
while command != "quit":
    command = input("Nhập lệnh (quit để thoát): ")
    if command != "quit":
        print(f"Đang chạy: {command}")

Cảnh giác: vì điều kiện luôn True, phảibreak nằm trên đường thực thi, nếu không sẽ infinite loop.

8

while ... else

Python cho phép gắn else vào sau while. Khối else chạy khi loop kết thúc bình thường (điều kiện thành False), không chạy nếu loop thoát bằng break.

i = 1
while i <= 3:
    print(i)
    i += 1
else:
    print("Loop chạy hết, không gặp break")
# 1
# 2
# 3
# Loop chạy hết, không gặp break

Có break thì else bị bỏ qua:

i = 1
while i <= 3:
    if i == 2:
        break
    i += 1
else:
    print("Không in dòng này")

Cú pháp này ít gặp; chủ yếu hữu ích khi cần phân biệt "tìm được" (break) và "tìm hết không thấy" (else chạy).

9

So sánh while vs for

Tiêu chí for while
Số lần lặp Biết trước (độ dài iterable) Phụ thuộc điều kiện động
Đầu vào Một iterable (list, range, file, ...) Một biểu thức boolean
Cập nhật biến đếm Tự động Phải tự cập nhật trong body
Nguy cơ infinite loop Thấp Cao nếu quên update
Use case AI/ML Duyệt dataset, epoch cố định Retry call, early stopping, streaming

Quy tắc đơn giản: có iterable thì dùng for, có điều kiện thì dùng while.

10

Use case: retry API với exponential backoff

Khi gọi API model (OpenAI, Anthropic, HuggingFace Inference, ...), đôi khi gặp lỗi mạng hoặc rate limit (HTTP 429, 503). Pattern chuẩn là retry: thử lại vài lần, mỗi lần đợi lâu hơn lần trước — gọi là exponential backoff.

import time
import random

max_retries = 5
attempt = 0
delay = 1.0      # giây

while attempt < max_retries:
    try:
        # giả lập gọi API — thực tế là openai.chat.completions.create(...)
        if random.random() < 0.7:
            raise ConnectionError("503 Service Unavailable")
        result = "OK"
        print(f"Thành công ở lần thử {attempt + 1}")
        break
    except ConnectionError as e:
        attempt += 1
        if attempt >= max_retries:
            print(f"Hết {max_retries} lần thử, bỏ cuộc")
            raise
        print(f"Lần {attempt} lỗi: {e}. Đợi {delay}s rồi thử lại")
        time.sleep(delay)
        delay *= 2     # 1s, 2s, 4s, 8s, 16s

Ý nghĩa từng phần:

  • while attempt < max_retries — giới hạn số lần thử, không treo vô hạn.
  • break — thoát ngay khi thành công.
  • delay *= 2 — mỗi lần thất bại, đợi gấp đôi lần trước. Server có thời gian phục hồi, client không spam.
  • raise ở lần cuối — ném exception ra ngoài để caller biết thật sự lỗi.

Pattern này gần như bắt buộc khi pipeline AI gọi nhiều API liên tiếp trong một batch.

11

Bài tập

Bài 1: Đoán số bằng binary search. Máy chọn ngẫu nhiên một số bí mật từ 1 đến 100. Viết chương trình tự đoán bằng binary search, in ra mỗi lần đoán và số lần đoán tổng cộng. Với khoảng 1-100, binary search cần tối đa 7 lần.

import random

secret = random.randint(1, 100)
low, high = 1, 100
attempts = 0

# TODO: dùng while để binary search
# - guess = (low + high) // 2
# - nếu guess == secret -> break
# - nếu guess < secret  -> low = guess + 1
# - nếu guess > secret  -> high = guess - 1

Bài 2: Đếm số chữ số của n. Cho một số nguyên dương n (ví dụ n = 12345), đếm xem nó có bao nhiêu chữ số bằng vòng lặp while và phép chia nguyên //. Không dùng str(n) rồi lấy len.

n = 12345
count = 0

# TODO: while n > 0 -> n //= 10, count += 1
# Kết quả mong đợi: count = 5

Mở rộng: xử lý cả trường hợp n = 0 (kết quả nên là 1) và n < 0 (lấy giá trị tuyệt đối trước).

12

Tóm tắt

  • while condition: lặp khi condition còn True; kiểm tra lại đầu mỗi iteration.
  • Luôn có 3 phần: khởi tạo, điều kiện, cập nhật biến điều kiện — quên phần thứ 3 là infinite loop.
  • Dừng loop đang treo: Ctrl + C trong terminal; nút Stop / Interrupt trong Colab / Jupyter.
  • break thoát ngay loop chứa nó; continue bỏ qua phần còn lại của iteration và lên kiểm tra điều kiện.
  • Pattern while True + break dùng khi điều kiện thoát ở giữa loop.
  • while ... else: else chạy khi loop kết thúc bình thường, không chạy nếu thoát bằng break.
  • Dùng for với iterable biết trước, dùng while với điều kiện động (retry, streaming, early stopping).
  • Exponential backoff = retry với delay nhân đôi sau mỗi lần thất bại — pattern chuẩn khi gọi API model.

Bài tiếp theo sẽ học hàm (function) — đóng gói logic thành đơn vị tái sử dụng, bước đầu để viết code AI có cấu trúc.