Vòng lặp while
Bạn sẽ học được
- Cấu trúc
whilevà điều kiện dừng. break,continue,while Truecó kiểm soát.while ... elsevà khác biệt vớifor ... else.- Mẫu vòng lặp kiểm tra đầu vào.
- Cách nhận diện và tránh vòng lặp vô hạn.
Khái niệm cốt lõi
while lặp chừng nào điều kiện còn đúng. Khác for — vốn biết trước dãy cần duyệt — while dùng khi số lần lặp phụ thuộc vào trạng thái thay đổi trong thân vòng lặp.
n = 5
while n > 0:
print(n)
n -= 1
print("Bắt đầu!")5
4
3
2
1
Bắt đầu!Ba phần bắt buộc phải có:
- Khởi tạo biến điều kiện trước vòng lặp (
n = 5). - Điều kiện trong
while(n > 0). - Cập nhật biến trong thân (
n -= 1).
Thiếu phần 3 là vòng lặp vô hạn. Đây là lỗi phổ biến nhất với while, và nó không báo lỗi — chương trình chỉ treo cho đến khi bị dừng.
break — thoát giữa chừng
break thoát ngay vòng lặp gần nhất, bỏ qua phần còn lại của thân và điều kiện:
n = 0
while True:
n += 1
if n == 3:
break
print(n)3while True là vòng lặp vô hạn có chủ đích; break là lối ra. Mẫu này hợp lý khi điều kiện dừng nằm giữa thân — ví dụ sau khi đọc và kiểm tra dữ liệu — vì while True tránh phải lặp lại điều kiện ở hai nơi.
Nhưng while True chỉ an toàn khi mọi nhánh đều có đường ra. Nếu break nằm trong một if hiếm khi đúng, vòng lặp có thể chạy mãi. Khi viết, hãy tự hỏi: "dữ liệu xấu nhất có làm điều kiện break không bao giờ đúng không?"
continue — bỏ qua phần còn lại
continue nhảy về đầu vòng lặp, bỏ qua các lệnh phía sau trong thân:
n = 0
while n < 5:
n += 1
if n == 3:
continue
print(n)1
2
4
5Điều kiện n < 5 vẫn được kiểm tra lại sau continue. Cẩn thận: nếu continue nằm trước bước cập nhật, biến có thể không bao giờ đổi và vòng lặp treo:
n = 0
while n < 5:
if n == 3:
continue # n không bao giờ tăng khi n == 3
n += 1Đây là biến thể nguy hiểm của vòng lặp vô hạn: chỉ treo khi chạm đúng giá trị 3.
while ... else
Giống for, while có nhánh else chạy khi điều kiện sai mà không có break:
n = 5
while n > 0:
n -= 1
else:
print("Kết thúc bình thường")Kết thúc bình thườngCó break thì else không chạy:
n = 5
while n > 0:
n -= 1
if n == 2:
break
else:
print("Không in dòng này")
print("sau break", n)sau break 2Trong thực tế, while ... else hiếm dùng và dễ gây nhầm. Nếu logic cần "tìm thấy hay không", một biến cờ hoặc hàm có return thường rõ hơn.
Mẫu kiểm tra đầu vào
Đây là ứng dụng thực tế nhất của while khi mới học — lặp cho đến khi người dùng nhập đúng:
while True:
raw = input("Điểm: ")
try:
score = float(raw)
except ValueError:
print("Vui lòng nhập số")
continue
if 0 <= score <= 100:
break
print("Điểm phải từ 0 đến 100")Luồng chạy:
- Gõ
abc→ValueError→ in nhắc →continue→ hỏi lại. - Gõ
150→ đọc được số nhưng ngoài khoảng → in nhắc → hết thân → hỏi lại. - Gõ
85→ hợp lệ →break.
Mọi nhánh đều quay về đầu vòng lặp, và chỉ nhánh hợp lệ mới thoát. Cấu trúc try/except + continue + break này là khuôn mẫu chuẩn cho nhập liệu tương tác.
Khi kiểm thử, tách phần đọc dữ liệu khỏi phần kiểm tra để không phải gõ tay:
def doc_diem(raw):
try:
score = float(raw)
except (TypeError, ValueError):
return None
if not 0 <= score <= 100:
return None
return score
print(doc_diem("85"), doc_diem("abc"), doc_diem("150"))85.0 None NoneVòng lặp vô hạn — nhận diện
Ba nguyên nhân thường gặp:
| Nguyên nhân | Ví dụ | Cách sửa |
|---|---|---|
| Quên cập nhật | while n > 0: print(n) | Thêm n -= 1 |
| Cập nhật sai hướng | while n > 0: n += 1 | Đổi thành -= |
continue trước bước cập nhật | if x: continue đặt trên i += 1 | Đưa cập nhật lên trước |
| Điều kiện không bao giờ sai | while n != 10 với bước nhảy 3 | Dùng < hoặc kiểm tra bước |
Trong terminal, Ctrl+C gửi KeyboardInterrupt và dừng chương trình. Trong notebook, nút stop làm việc tương tự. Nếu vòng lặp chạy trong job production, nó có thể treo cả worker — vì vậy với dữ liệu bên ngoài, nên có thêm giới hạn số lần thử:
attempts = 0
while attempts < 3:
attempts += 1
...
breakGiới hạn cứng là lưới an toàn: dù logic sai, chương trình vẫn kết thúc.
while hay for?
| Tình huống | Chọn |
|---|---|
| Duyệt list, chuỗi, dict, file | for |
| Biết trước số lần lặp | for + range |
| Lặp đến khi điều kiện đổi (nhập liệu, chờ trạng thái) | while |
| Đọc file/stream đến hết | for |
Vòng lặp có break giữa thân | while True hoặc for tuỳ dữ liệu |
Quy tắc: nếu có thể viết bằng for, hãy viết bằng for — ít khả năng treo hơn. while dành cho trường hợp số lần lặp thực sự chưa biết.
Thực hành
- In đếm ngược từ 5 về 1 rồi in "Bắt đầu!".
- Dùng
while True+breakđể thoát khin == 3. - Dùng
continueđể bỏ qua số 3 trong dãy 1–5. - Viết vòng lặp nhập điểm hợp lệ 0–100, thử cả chữ và số ngoài khoảng.
- Cố ý tạo vòng lặp vô hạn bằng cách bỏ
n -= 1, dừng bằngCtrl+C. - Thêm giới hạn 3 lần thử vào vòng lặp nhập điểm.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
| Chương trình treo | Không cập nhật biến điều kiện | Thêm bước cập nhật |
| Treo chỉ khi gặp một giá trị | continue trước bước cập nhật | Đưa cập nhật lên trước continue |
| Vòng lặp chạy 0 lần | Điều kiện sai ngay từ đầu | Kiểm tra giá trị khởi tạo |
else không chạy | Có break | Bỏ break hoặc bỏ else |
NameError sau vòng lặp | Biến chỉ gán trong nhánh hiếm | Khởi tạo trước vòng lặp |
| Nhập đúng vẫn hỏi lại | continue đặt sau break không đúng chỗ | Rà luồng từng nhánh |
| Job production treo | Dữ liệu ngoài làm điều kiện không đổi | Thêm giới hạn số lần thử |
Tóm tắt
whilelặp theo điều kiện; phải có khởi tạo, điều kiện, cập nhật.breakthoát ngay;continuevề đầu vòng, bỏ phần còn lại.while ... elsechạy khi không cóbreak— hiếm dùng.- Mẫu nhập liệu:
while True+try/except+continue+break. - Luôn có lối ra cho mọi nhánh; thêm giới hạn cứng khi đọc dữ liệu ngoài.
Dùng ← → để chuyển bài