2.12. Vòng lặp¶
Một vòng lặp chạy đi chạy lại cùng một khối mã. Python có hai dạng: while, tiếp tục chạy miễn là một điều kiện còn đúng, và for, duyệt qua từng phần tử của một dãy.
while liên tục kiểm tra một điều kiện; for duyệt qua một dãy cho đến khi hết.¶
2.12.1. Vòng lặp while¶
Vòng lặp while kiểm tra điều kiện trước mỗi lần lặp và chạy thân vòng lặp cho đến khi điều kiện trở thành sai:
count = 0
while count < 5:
print(count)
count += 1
Kết quả:
0
1
2
3
4
Nếu điều kiện đúng ngay từ đầu và không bao giờ trở thành sai, vòng lặp sẽ chạy mãi mãi. while True: là thành ngữ chuẩn cho một vòng lặp chính, thoát ra bằng break:
while True:
step()
if done():
break
2.12.2. Vòng lặp for¶
Vòng lặp for duyệt qua các phần tử của một iterable -- một list, tuple, string, bytes, dict, hoặc bất cứ thứ gì hỗ trợ iteration:
for fruit in ["apple", "banana", "cherry"]:
print(fruit)
Kết quả:
apple
banana
cherry
Dạng tương tự cũng hoạt động trên chuỗi ký tự, khi đó mỗi phần tử là một chuỗi gồm một ký tự:
for letter in "OpenMV":
print(letter)
Kết quả:
O
p
e
n
M
V
Duyệt qua một dict trực tiếp trả về các khóa của nó, theo thứ tự chèn vào:
for key in {"a": 1, "b": 2}:
print(key)
Kết quả:
a
b
Mỗi lần lặp gán biến vòng lặp (fruit, letter, key) cho phần tử tiếp theo. Sau khi vòng lặp kết thúc, biến giữ giá trị từ lần lặp cuối cùng.
2.12.3. range¶
Đối với các vòng lặp trên một phạm vi số, dùng range():
range(stop)-- 0, 1, ..., stop - 1.range(start, stop)-- start, start + 1, ..., stop - 1.range(start, stop, step)-- với bước tùy chỉnh (giá trị âm đếm ngược).
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(2, 8, 2): # 2, 4, 6
print(i)
for i in range(10, 0, -1): # 10, 9, ..., 1
print(i)
range() tạo ra các giá trị theo kiểu lazy -- nó không tạo một list trong bộ nhớ. Để lấy một list thực sự, hãy bọc lại: list(range(10)).
2.12.4. enumerate¶
Khi vòng lặp cần cả chỉ số lẫn phần tử, enumerate() trả về từng cặp (index, item):
for i, name in enumerate(["a", "b", "c"]):
print(i, name)
# 0 a
# 1 b
# 2 c
Bắt đầu chỉ số từ một giá trị khác không bằng cách truyền đối số thứ hai: enumerate(items, start=1).
2.12.5. zip¶
Để duyệt hai (hoặc nhiều hơn) iterable cùng lúc theo từng bước, dùng zip(). Hàm này trả về một tuple cho mỗi vị trí và dừng lại ở đầu vào ngắn nhất:
names = ["alice", "bob", "carol"]
scores = [88, 92, 70]
for name, score in zip(names, scores):
print(name, score)
Kết quả:
alice 88
bob 92
carol 70
2.12.6. Gán nội tuyến với :=¶
Toán tử walrus := là một phép gán đồng thời cũng là một biểu thức. Nó gán tên và trả về cùng giá trị đó ngay lập tức. Trong vòng lặp while, điều này rút gọn mẫu "đọc, kiểm tra, thân" thông thường thành một dòng:
# without walrus
value = next_value()
while value is not None:
process(value)
value = next_value()
# with walrus
while (value := next_value()) is not None:
process(value)
Hai dạng thực hiện cùng một việc. Hãy dùng := khi việc lặp lại phép gán thực sự ảnh hưởng đến khả năng đọc; đừng dùng nó chỉ để tỏ ra khôn ngoan. Dấu ngoặc đơn là bắt buộc ở hầu hết các vị trí để giữ biểu thức không mơ hồ.