Bài 2.8. Vòng lặp while trong Python

Bài 2.8. Vòng lặp while trong Python
Chào mừng các bạn quay trở lại với series học Python! Trong cuộc sống cũng như trong lập trình, chúng ta thường xuyên phải đối mặt với những công việc cần lặp đi lặp lại. Hãy tưởng tượng bạn phải gửi 100 email giống hệt nhau, chỉ khác tên người nhận. Thay vì sao chép và dán 100 lần, chúng ta cần một cách tự động hóa quy trình đó. Đây chính là lúc các vòng lặp tỏa sáng!
Python cung cấp hai loại vòng lặp chính: for
và while
. Trong bài học này, chúng ta sẽ tập trung vào vòng lặp while
- một công cụ cực kỳ linh hoạt cho phép bạn thực thi một khối lệnh miễn là một điều kiện nhất định còn đúng.
1. Cú pháp cơ bản của vòng lặp while
Vòng lặp while
có cấu trúc khá đơn giản và trực quan:
while dieu_kien:
# Khối lệnh sẽ được thực thi lặp đi lặp lại
# Miễn là 'dieu_kien' còn là True
# ...
# (Thường có một thao tác cập nhật nào đó ảnh hưởng đến 'dieu_kien')
Giải thích:
while
: Đây là từ khóa báo hiệu bắt đầu một vòng lặpwhile
.dieu_kien
: Đây là một biểu thức logic. Trước mỗi lần lặp, Python sẽ kiểm tra xem biểu thức này có trả về giá trịTrue
hay không.- Nếu
dieu_kien
làTrue
, khối lệnh bên trong (phần được thụt vào) sẽ được thực thi. - Nếu
dieu_kien
làFalse
, vòng lặp sẽ kết thúc và chương trình sẽ tiếp tục thực thi các lệnh sau khốiwhile
.
- Nếu
- Khối lệnh: Bao gồm một hoặc nhiều câu lệnh Python được thụt vào cùng một mức so với từ khóa
while
. Đây là phần công việc sẽ được lặp lại.
Điểm cốt lõi cần nhớ với while
: Khối lệnh sẽ chạy không ngừng nếu dieu_kien
luôn luôn là True
. Do đó, bên trong khối lệnh, bạn phải có một cách nào đó để tác động lên dieu_kien
, khiến nó cuối cùng trở thành False
để vòng lặp có thể dừng lại. Nếu không, bạn sẽ tạo ra một vòng lặp vô hạn!
2. Ví dụ minh họa vòng lặp while
Hãy cùng xem qua một vài ví dụ để hiểu rõ hơn cách while
hoạt động.
Ví dụ 1: Đếm số đơn giản
Đây là ví dụ kinh điển nhất khi bắt đầu với while
: đếm từ một số bắt đầu đến một số kết thúc.
# Ví dụ: Đếm từ 1 đến 5 và in ra màn hình
print("Bắt đầu đếm...")
so_dem = 1 # Khởi tạo biến đếm
while so_dem <= 5: # Điều kiện: tiếp tục lặp nếu so_dem còn nhỏ hơn hoặc bằng 5
print(f"Số hiện tại: {so_dem}")
so_dem = so_dem + 1 # Quan trọng: Tăng biến đếm lên 1 sau mỗi lần lặp
print("Đã đếm xong!")
Giải thích code:
so_dem = 1
: Chúng ta khởi tạo một biếnso_dem
với giá trị ban đầu là 1.while so_dem <= 5
: Python kiểm tra điều kiện. Lần đầu tiên,1 <= 5
làTrue
, nên khối lệnh bên trong được thực thi.print(f"Số hiện tại: {so_dem}")
: In ra giá trị hiện tại củaso_dem
.so_dem = so_dem + 1
: Đây là bước cập nhật quan trọng. Giá trị củaso_dem
được tăng lên 1. Nếu không có dòng này,so_dem
sẽ mãi mãi là 1, điều kiệnso_dem <= 5
luôn đúng, và vòng lặp sẽ chạy vô hạn!- Sau khi tăng
so_dem
, vòng lặp quay lại bước 2 để kiểm tra lại điều kiện. Quá trình này tiếp tục cho đến khiso_dem
tăng lên 6. Lúc này, điều kiện6 <= 5
làFalse
, vòng lặp kết thúc. print("Đã đếm xong!")
: Dòng này nằm ngoài vòng lặp và chỉ được thực thi sau khi vòng lặpwhile
đã hoàn thành.
Kết quả:
Bắt đầu đếm...
Số hiện tại: 1
Số hiện tại: 2
Số hiện tại: 3
Số hiện tại: 4
Số hiện tại: 5
Đã đếm xong!
Ví dụ 2: Yêu cầu nhập liệu hợp lệ từ người dùng
Vòng lặp while
rất hữu ích khi bạn muốn đảm bảo người dùng nhập vào dữ liệu đúng định dạng hoặc nằm trong một phạm vi cho phép. Vòng lặp sẽ tiếp tục chạy cho đến khi nhận được đầu vào hợp lệ.
# Ví dụ: Yêu cầu người dùng nhập một số nguyên dương
so_nhap = -1 # Khởi tạo giá trị ban đầu không hợp lệ để đảm bảo vòng lặp chạy ít nhất 1 lần
while so_nhap <= 0:
print("---") # Phân cách các lần nhập
gia_tri_nhap = input("Vui lòng nhập một số nguyên dương: ")
try:
so_nhap = int(gia_tri_nhap) # Thử chuyển đổi sang số nguyên
if so_nhap <= 0:
print(f"Lỗi: '{so_nhap}' không phải là số dương. Xin hãy nhập lại.")
except ValueError:
print(f"Lỗi: '{gia_tri_nhap}' không phải là một số nguyên hợp lệ. Xin hãy nhập lại.")
# Giữ so_nhap <= 0 (hoặc giá trị cũ không hợp lệ) để vòng lặp tiếp tục
print(f"Tuyệt vời! Bạn đã nhập số dương: {so_nhap}")
Giải thích code:
so_nhap = -1
: Khởi tạoso_nhap
với một giá trị chắc chắn làm cho điều kiệnso_nhap <= 0
làTrue
ngay từ đầu.while so_nhap <= 0
: Vòng lặp sẽ tiếp tục chừng nàoso_nhap
chưa phải là một số dương.input(...)
: Nhận đầu vào từ người dùng dưới dạng chuỗi.try...except ValueError
: Chúng ta dùng khốitry-except
để xử lý trường hợp người dùng nhập vào không phải là số (ví dụ: chữ "abc").try
: Thử thực hiệnint(gia_tri_nhap)
. Nếu thành công, gán kết quả choso_nhap
.if so_nhap <= 0
: Nếu chuyển đổi thành công nhưng số đó không dương, in thông báo lỗi. Điều kiệnwhile
vẫn đúng ở lần kiểm tra tiếp theo.except ValueError
: Nếuint()
thất bại (người dùng nhập chữ), bắt lỗiValueError
, in thông báo lỗi. Quan trọng làso_nhap
không được cập nhật giá trị mới hợp lệ, nên điều kiệnwhile
vẫn đúng.
- Vòng lặp chỉ kết thúc khi người dùng nhập một chuỗi có thể chuyển đổi thành số nguyên và số nguyên đó lớn hơn 0.
Ví dụ 3: Sử dụng giá trị đặc biệt (Sentinel Value) để dừng lặp
Đôi khi, bạn muốn lặp lại một hành động cho đến khi người dùng nhập một giá trị đặc biệt (gọi là sentinel) để báo hiệu kết thúc.
# Ví dụ: Tính tổng các số người dùng nhập, dừng khi nhập số 0
tong = 0
so_hien_tai = None # Khởi tạo khác 0 để vòng lặp bắt đầu
print("Nhập các số bạn muốn tính tổng.")
print("Nhập số 0 để kết thúc và xem kết quả.")
while so_hien_tai != 0: # Điều kiện: tiếp tục nếu số nhập vào chưa phải là 0
try:
chuoi_nhap = input("Nhập số (nhập 0 để dừng): ")
so_hien_tai = int(chuoi_nhap)
# Chỉ cộng vào tổng nếu số nhập không phải là 0 (số sentinel)
if so_hien_tai != 0:
tong = tong + so_hien_tai
# Nếu so_hien_tai là 0, không cộng, và vòng lặp sẽ dừng ở lần kiểm tra tiếp theo
except ValueError:
print("Đó không phải là số hợp lệ. Vui lòng thử lại.")
# Không cập nhật so_hien_tai, có thể giữ giá trị cũ hoặc để là None
# để đảm bảo vòng lặp không dừng vì lỗi nhập liệu
# Dòng này chỉ chạy khi vòng lặp kết thúc (khi so_hien_tai == 0)
print(f"Tổng các số bạn đã nhập là: {tong}")
Giải thích code:
tong = 0
,so_hien_tai = None
: Khởi tạo tổng và biến lưu số hiện tại. GánNone
(hoặc bất kỳ giá trị nào khác 0) choso_hien_tai
để đảm bảo điều kiệnso_hien_tai != 0
làTrue
lúc bắt đầu.while so_hien_tai != 0
: Vòng lặp tiếp tục miễn là người dùng chưa nhập số 0.- Bên trong vòng lặp, chương trình yêu cầu nhập số, chuyển đổi sang
int
(với xử lý lỗi). if so_hien_tai != 0: tong = tong + so_hien_tai
: Chỉ cộng số vàotong
nếu nó không phải là giá trị sentinel (số 0).- Khi người dùng nhập
0
,so_hien_tai
sẽ được gán là0
. Ở lần kiểm tra điều kiện tiếp theo,0 != 0
làFalse
, vòng lặp kết thúc. - Cuối cùng, in ra tổng tích lũy được.
3. Lệnh break
và else
trong vòng lặp while
Lệnh break
Đôi khi, bạn muốn thoát khỏi vòng lặp while
ngay lập tức mà không cần chờ điều kiện trở thành False
. Lệnh break
cho phép bạn làm điều đó. Khi break
được thực thi, vòng lặp sẽ dừng ngay lập tức, và chương trình nhảy đến câu lệnh đầu tiên sau khối while
.
# Ví dụ: Tìm số ngẫu nhiên cho đến khi gặp số lớn hơn 90
import random
print("Bắt đầu tìm số may mắn (> 90)...")
so_lan_thu = 0
while True: # Vòng lặp này có vẻ vô hạn?
so_ngau_nhien = random.randint(1, 100) # Sinh số ngẫu nhiên từ 1 đến 100
so_lan_thu += 1
print(f"Lần thử {so_lan_thu}: {so_ngau_nhien}")
if so_ngau_nhien > 90:
print(f"Tìm thấy số {so_ngau_nhien} lớn hơn 90!")
break # Thoát khỏi vòng lặp ngay lập tức!
print(f"Kết thúc sau {so_lan_thu} lần thử.")
Giải thích code:
while True
: Chúng ta tạo một vòng lặp có điều kiện luôn đúng. Về lý thuyết, nó sẽ chạy mãi mãi.- Bên trong, chúng ta sinh số ngẫu nhiên và tăng bộ đếm.
if so_ngau_nhien > 90: break
: Đây là điều kiện thoát thực sự. Nếu số ngẫu nhiên lớn hơn 90, thông báo được in ra vàbreak
được gọi, chấm dứt vòng lặpwhile True
ngay lập tức.- Cách dùng
while True
kết hợp vớibreak
rất phổ biến khi điều kiện dừng phức tạp hoặc cần kiểm tra ở giữa vòng lặp.
Mệnh đề else
sau while
Đây là một tính năng ít được biết đến hơn của while
(và for
) trong Python. Khối lệnh trong mệnh đề else
sẽ được thực thi chỉ khi vòng lặp kết thúc một cách bình thường (tức là do điều kiện while
trở thành False
), chứ không phải do lệnh break
.
# Ví dụ: Kiểm tra xem một số có phải là số nguyên tố không (cách đơn giản)
num = 13
uoc_so = 2 # Bắt đầu kiểm tra ước từ 2
print(f"Kiểm tra số {num}...")
while uoc_so < num:
if num % uoc_so == 0:
print(f"{num} không phải là số nguyên tố (chia hết cho {uoc_so}).")
break # Tìm thấy ước, không phải số nguyên tố -> thoát lặp
uoc_so += 1
else:
# Khối này chỉ chạy nếu vòng lặp while hoàn thành mà không gặp 'break'
# Điều này có nghĩa là không tìm thấy ước nào từ 2 đến num-1
if num > 1: # Số nguyên tố phải lớn hơn 1
print(f"{num} là số nguyên tố!")
else:
print(f"{num} không phải là số nguyên tố.")
print("-" * 10)
# Thử với số không nguyên tố
num = 12
uoc_so = 2
print(f"Kiểm tra số {num}...")
while uoc_so < num:
if num % uoc_so == 0:
print(f"{num} không phải là số nguyên tố (chia hết cho {uoc_so}).")
break
uoc_so += 1
else:
# Khối này sẽ KHÔNG chạy vì vòng lặp đã bị dừng bởi 'break'
print(f"{num} là số nguyên tố!")
Giải thích code:
- Trong trường hợp
num = 13
, vòng lặpwhile
chạy hết các giá trị củauoc_so
từ 2 đến 12. Không có giá trị nào mà13 % uoc_so == 0
, nênbreak
không bao giờ được gọi. Vòng lặp kết thúc bình thường khiuoc_so
trở thành 13 (điều kiệnuoc_so < num
làFalse
). Do đó, khốielse
được thực thi, in ra "13 là số nguyên tố!". - Trong trường hợp
num = 12
, khiuoc_so
là 2,12 % 2 == 0
làTrue
. Lệnhprint
trongif
được thực thi và sau đóbreak
được gọi. Vòng lặp kết thúc dobreak
. Vì vậy, khốielse
không được thực thi.
4. Cạm bẫy cần tránh: Vòng lặp vô hạn
Như đã đề cập, lỗi phổ biến nhất và nguy hiểm nhất với while
là vòng lặp vô hạn. Điều này xảy ra khi điều kiện của vòng lặp while
không bao giờ trở thành False
.
# Cảnh báo: VÍ DỤ VỀ VÒNG LẶP VÔ HẠN - ĐỪNG CHẠY NẾU KHÔNG BIẾT CÁCH DỪNG!
# (Thường phải nhấn Ctrl + C trong terminal để dừng)
# dem = 0
# while dem < 5:
# print("Vẫn đang chạy...")
# # Lỗi: Quên không cập nhật biến 'dem'. 'dem' sẽ luôn là 0.
# # dem = dem + 1 # Dòng này bị thiếu hoặc bị comment đi
Làm thế nào để tránh?
- Luôn đảm bảo có ít nhất một con đường trong khối lệnh
while
sẽ dẫn đến việc điều kiện trở thànhFalse
. - Kiểm tra kỹ các biến tham gia vào điều kiện và đảm bảo chúng được cập nhật đúng cách trong mỗi lần lặp.
- Khi sử dụng
while True
, phải chắc chắn có một lệnhbreak
sẽ được thực thi ở một thời điểm nào đó dưới một điều kiện hợp lý. - Trong quá trình gỡ lỗi (debug), nếu nghi ngờ vòng lặp vô hạn, hãy thêm các lệnh
print
để theo dõi giá trị của các biến điều kiện qua từng vòng lặp.
Vòng lặp while
là một công cụ mạnh mẽ để kiểm soát luồng thực thi của chương trình dựa trên các điều kiện động. Hiểu rõ cách hoạt động, các ví dụ ứng dụng và cách tránh lỗi vòng lặp vô hạn sẽ giúp bạn viết code Python hiệu quả và linh hoạt hơn rất nhiều!
Comments