Mệnh đề else với vòng lặp trong Python

Đối với nhiều người, cấu trúc rẽ nhánh If...elif...else... hay cấu trúc lặp for...in...while... là những điều vô cùng căn bản không chỉ trong Python mà cả trong bất kì một ngôn ngữ lập trình nào. Nhưng đã có ai thử nghĩ rằng hợp thể 2 cấu trúc này lại thì nó sẽ ra cái gì chưa? Hôm nay, mình mạo muội xin phép chia sẻ với mọi người một tính năng rất hay và thú vị của riêng Python mà không phải ai cũng biết (ai biết rồi cũng đừng gạch đá, tội nghiệp mình :innocent:).

Cấu trúc tổng quát

# else with for loop
for item in iterable:
    ...  # statements
else:
    ...  # statements

# else with while loop
while test:
    ...  # statements
else:
    ...  # statements

Cách dùng

Chức năng và cách dùng của 2 vòng lặp này đã quá cơ bản rồi, mình không nhắc lại nữa. Bài viết này mình sẽ chỉ đề cập đến mệnh đề else sau vòng lặp thôi.
Nói một cách ngắn gọn, mệnh đề else sẽ chỉ được thực thi khi vòng lặp được thoát ra một cách bình thường, tức là thoát ra mà không gặp lệnh break. Cụ thể, đối với vòng lặp for, đó là khi biến item được gán với từng phần tử của iterable (ở đây có thể là iterators, sequences như lists, tuples, sets, dictionaries’ keys,…), từ đầu đến cuối. Còn với vòng lặp while, đó là khi test đang từ True trở thành False.
Có vẻ hơi khó hiểu, vậy ta lấy một vài ví dụ minh họa thúc đẩy tuần hoàn não nào!

Ví dụ

Với vòng lặp for

bag1 = ['knife', 'grenade', 'gun', 'rifle', 'dynamite']
for item in bag1:
    if item == 'bomb':
        print("Dangerous, take it out of here!!!")
        break
    print("There is a {} in bag1.".format(item))
else:
    # sẽ ĐƯỢC thực thi bởi vì bag1 không chứa 'bomb', vòng lặp được thoát ra
    # bình thường sau khi item được gán lần lượt với từng objects trong bag1
    print("OK everyone, it's safe.")

bag2 = ['biscuit', 'apple', 'samsung', 'water', 'ice lolly', 'lemonade']
for item in bag2:
    if item == 'water':
        print("You can run but you can't hide!")
        break
else:
    # sẽ KHÔNG được thực thi vì khi item được gán cho 'water', mệnh đề if trở
    # thành đúng và lệnh break khiến vòng lặp thoát ra ngay lập tức
    print("Died of thirst.")

Với vòng lặp while

you_love_me = True
I_love_you = True
count = 0
while you_love_me and I_love_you:
    print("Let's have a date!")
    count += 1
    print("Dated {} time(s):".format(count))
    if count >= 100:
        print("Oh I'm fed up with you!")
        # lệnh print dưới sẽ được thực thi do vòng lặp thoát ra khi điều
        # điều kiện trở thành False
        I_love_you = False
        # tuy nhiên, nếu thay dòng trên bằng break thì lệnh print sẽ bị
        # bỏ qua
else:
    print("No more gifts. I'm rich.")

chú ý: Nếu điều kiện của vòng lặp while False ngay từ đầu thì mệnh đề else vẫn sẽ được thực hiện.

Chức năng

Sau khi nói một thôi một hồi như vậy, rốt cuộc việc kết hợp mệnh đề else với vòng lặp như trên có tác dụng gì? Câu trả lời đơn giản là làm cho code trở nên ngắn gọn và dễ hiểu hơn.

contacts = [...]
# version 1
found = False
for contact in contacts:
    if contact == 'Cortana':
        found = True
        print("Hey, I found {}'s number.".format(contact))
        break
if not found:
    print("How do I call her now?")

# version 2
for contact in contacts:
    if contact == 'Cortana':
        print("Hey, I found {}'s number.".format(contact))
        break
else:
    print("How do I call her now?")

Như các bạn có thể thấy, version 2 rõ ràng ngắn gọn hơn, không phải dùng biến found để kiểm tra xem liệu có tìm được 'Cortana' trong contacts không. Và theo như ai đó từng nói (mình quên mất tiêu rồi), the best code is no code at all.

P/s: Lần đầu tiên viết bài, có gì không phải mong mọi người bỏ quá cho :grin: (chả biết mình ngồi viết cái bài này bao lâu rồi nữa :rolling_eyes:)

6 Likes

for … else:

else sẽ thực hiện khi vòng lặp FOR không BREAK.

try … else:

else sẽ thực hiện khi khi không xảy ra EXCEPTION

yep, nghĩ lại cũng đúng :grin:

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?