2.13. Điều khiển vòng lặp

Hai từ khóa thay đổi cách vòng lặp chạy:

  • break -- thoát khỏi vòng lặp ngay lập tức.

  • continue -- bỏ qua phần còn lại của lần lặp hiện tại và bắt đầu lần tiếp theo.

Cả hai đều áp dụng cho vòng lặp trong cùng mà chúng xuất hiện.

2.13.1. break

Dùng break để dừng vòng lặp ngay khi một điều kiện được thỏa mãn. Mẫu "tìm kiếm và dừng" kinh điển:

found = None
for item in items:
    if matches(item):
        found = item
        break

if found is not None:
    print("found:", found)

Trong vòng lặp while True:, break là cách để kết thúc vòng lặp:

while True:
    line = next_line()
    if line == "quit":
        break
    process(line)

2.13.2. continue

Dùng continue để bỏ qua phần còn lại của thân vòng lặp và nhảy đến lần lặp tiếp theo. Hữu ích khi cần lọc các phần tử bên trong vòng lặp:

for n in numbers:
    if n < 0:
        continue            # skip negatives
    print(n)

Hiệu quả tương tự có thể được viết bằng một khối if bao quanh phần còn lại của thân vòng lặp. continue đôi khi rõ ràng hơn khi điều kiện bỏ qua dễ phát biểu hơn điều kiện giữ lại.

Bên trong vòng lặp, continue đóng vai trò tương tự như return sớm trong một hàm: bỏ qua các trường hợp không xử lý và giữ phần công việc chính ở mức thụt lề ngoài cùng. Vòng lặp lọc-và-xử-lý là dạng chuẩn tắc:

for item in items:
    if item is None:
        continue
    if not item.is_valid():
        continue
    process(item)

Dòng process(item) thụt vào là phần công việc thực sự; mỗi câu lệnh bảo vệ phía trên nêu rõ chính xác những phần tử nào bị bỏ qua.

2.13.3. else trên vòng lặp

Cả forwhile đều chấp nhận một khối else tùy chọn. Khối này chạy khi vòng lặp hoàn thành mà không gặp break. Cách dùng phổ biến nhất là vòng lặp tìm kiếm muốn có phương án dự phòng nếu không tìm thấy gì:

for item in items:
    if matches(item):
        print("found:", item)
        break
else:
    print("no match")

Nếu break được kích hoạt, khối else sẽ bị bỏ qua. Hãy đọc cấu trúc này là "for X in Y: ...; hoặc-ngược-lại, nếu chúng ta không bao giờ thoát ra, hãy làm Z."

2.13.4. Các mẫu vòng lặp phổ biến

Một số mẫu thường xuất hiện trong các tập lệnh thực tế:

  • Polling -- chờ đợi cho đến khi một điều kiện nào đó trở thành đúng trước khi tiếp tục. Thân vòng lặp dùng pass, câu lệnh không-làm-gì của Python; mỗi khối thụt vào phải chứa ít nhất một câu lệnh, và pass là cách nói "không làm gì ở đây":

    while not ready():
        pass
    proceed()
    
  • Máy trạng thái -- một vòng lặp while True: duy nhất chọn việc cần làm dựa trên một biến trạng thái. Hữu ích khi công việc phân chia rõ ràng thành một vài giai đoạn được đặt tên:

    state = "header"
    for line in lines:
        if state == "header":
            if line.startswith("---"):
                state = "body"
        elif state == "body":
            print(line)
    
  • Tích lũy -- xây dựng kết quả trong khi duyệt qua một dãy:

    total = 0
    for x in samples:
        total += x
    mean = total / len(samples)
    

    Nhiều vòng lặp tích lũy có một dạng tương đương một dòng sử dụng hàm tích hợp. Hãy dùng hàm tích hợp khi có thể:

    • sum() -- cộng tổng mọi phần tử trong một iterable.

    • max() / min() -- phần tử lớn nhất hoặc nhỏ nhất.

    • any() -- True nếu có ít nhất một phần tử là truthy.

    • all() -- True chỉ khi mọi phần tử đều là truthy.

    • sorted() -- một danh sách mới với các phần tử được sắp xếp theo thứ tự.

    • len() -- số lượng phần tử (khi iterable biết độ dài của nó).

    >>> samples = [3, 1, 4, 1, 5, 9, 2, 6]
    >>> sum(samples)
    31
    >>> sum(samples) / len(samples)        # mean
    3.875
    >>> max(samples)
    9
    >>> min(samples)
    1
    >>> sorted(samples)
    [1, 1, 2, 3, 4, 5, 6, 9]
    >>> any([False, False, True])
    True
    >>> all([True, True, False])
    False
    

    Phiên bản dùng hàm tích hợp ngắn gọn hơn, rõ ràng hơn và thường nhanh hơn so với tự viết vòng lặp tương tự.