Làm thế nào tôi có thể hiểu ý nghĩa của mệnh đề `other` của các vòng lặp Python?


191

Nhiều lập trình viên Python có thể không biết rằng cú pháp của whilevòng lặp và forvòng lặp bao gồm một else:mệnh đề tùy chọn :

for val in iterable:
    do_something(val)
else:
    clean_up()

Phần thân của elsemệnh đề là một vị trí tốt cho một số loại hành động dọn dẹp nhất định và được thực hiện khi chấm dứt bình thường của vòng lặp: Tức là, thoát khỏi vòng lặp với returnhoặc breakbỏ qua elsemệnh đề; thoát ra sau khi continuethực hiện nó Tôi biết điều này chỉ vì tôi chỉ nhìn nó (một lần nữa), bởi vì tôi không bao giờ có thể nhớ khi các elseđiều khoản được thực thi.

Luôn luôn? Về "thất bại" của vòng lặp, như tên cho thấy? Ngày chấm dứt thường xuyên? Ngay cả khi vòng lặp được thoát với return? Tôi không bao giờ có thể hoàn toàn chắc chắn mà không cần tìm kiếm nó.

Tôi đổ lỗi cho sự không chắc chắn dai dẳng của tôi đối với việc lựa chọn từ khóa: Tôi thấy elsevô cùng thiếu sót đối với ngữ nghĩa này. Câu hỏi của tôi không phải là "tại sao từ khóa này được sử dụng cho mục đích này" (mà tôi có thể bỏ phiếu để đóng, mặc dù chỉ sau khi đọc câu trả lời và nhận xét), nhưng tôi có thể nghĩ về elsetừ khóa như thế nào để ngữ nghĩa của nó có ý nghĩa, và tôi Do đó có thể nhớ nó?

Tôi chắc chắn đã có một số lượng lớn các cuộc thảo luận về vấn đề này và tôi có thể tưởng tượng rằng sự lựa chọn được đưa ra để thống nhất với điều khoản trycủa tuyên bố else:(mà tôi cũng phải tìm kiếm) và với mục tiêu không thêm vào danh sách Những từ dành riêng của Python. Có lẽ các lý do cho việc lựa chọn elsesẽ làm rõ chức năng của nó và làm cho nó dễ nhớ hơn, nhưng tôi sau khi kết nối tên với chức năng, không phải sau khi giải thích lịch sử.

Các câu trả lời cho câu hỏi này , mà câu hỏi của tôi đã được đóng lại ngắn gọn như một bản sao, chứa rất nhiều câu chuyện ngược thú vị. Câu hỏi của tôi có trọng tâm khác nhau (làm thế nào để kết nối ngữ nghĩa cụ thể elsevới lựa chọn từ khóa), nhưng tôi cảm thấy nên có một liên kết đến câu hỏi này ở đâu đó.


23
Làm thế nào về "nếu có một cái gì đó còn lại để lặp đi lặp lại ... khác"
OneCricketeer

4
Tôi nghĩ bạn có thể nhớ nó ngay bây giờ sau khi viết câu hỏi này :)
Jasper

11
các elsephương tiện cơ bản, "nếu điều kiện tiếp tục thất bại". Trong một vòng lặp for truyền thống, điều kiện tiếp tục thường là i < 42, trong trường hợp đó, bạn có thể xem phần đó làif i < 42; execute the loop body; else; do that other thing
njzk2

1
Đây là tất cả sự thật, và tôi đặc biệt thích câu trả lời drawoc, nhưng một điều cần xem xét là khác là một từ khóa có sẵn mà cũng làm cho cảm giác hơi tốt syntaxically. Bạn có thể biết thử / ngoại trừ và có thể thử / ngoại trừ / cuối cùng, nhưng nó cũng có cách khác - chạy mã này nếu không có ngoại lệ xảy ra. Đó là btw, không giống với việc đẩy mã này theo mệnh đề thử - xử lý ngoại lệ được sử dụng tốt nhất khi được nhắm mục tiêu hẹp. Vì vậy, trong khi nó có ý nghĩa về mặt khái niệm - theo một số câu trả lời ở đây - tôi nghĩ đó cũng là cách sử dụng lại từ khóa - hãy chạy nó trong một số điều kiện nhất định .
JL Peyret

1
@Falanwe, có một sự khác biệt khi mã được thoát ra break. Trường hợp sử dụng chính tắc là khi vòng lặp tìm kiếm một cái gì đó và phá vỡ khi nó tìm thấy nó. Việc elsenày chỉ được thực hiện nếu không tìm thấy gì.
alexis

Câu trả lời:


212

(Điều này được lấy cảm hứng từ câu trả lời của @Mark Tolonen.)

Một ifcâu lệnh chạy elsemệnh đề của nó nếu điều kiện của nó ước lượng thành false. Chính xác, một whilevòng lặp chạy mệnh đề khác nếu điều kiện của nó ước tính thành false.

Quy tắc này phù hợp với hành vi bạn mô tả:

  • Trong thực thi bình thường, vòng lặp while chạy liên tục cho đến khi điều kiện ước lượng thành false và do đó, tự nhiên thoát khỏi vòng lặp sẽ chạy mệnh đề khác.
  • Khi bạn thực thi một breakcâu lệnh, bạn thoát khỏi vòng lặp mà không đánh giá điều kiện, vì vậy điều kiện không thể đánh giá thành false và bạn không bao giờ chạy mệnh đề khác.
  • Khi bạn thực hiện một continuecâu lệnh, bạn đánh giá lại điều kiện và thực hiện chính xác những gì bạn thường làm khi bắt đầu một vòng lặp. Vì vậy, nếu điều kiện là đúng, bạn tiếp tục lặp, nhưng nếu nó sai, bạn chạy mệnh đề khác.
  • Các phương pháp khác để thoát khỏi vòng lặp, chẳng hạn như return, không đánh giá điều kiện và do đó không chạy mệnh đề khác.

forcác vòng lặp hành xử theo cùng một cách. Chỉ cần xem điều kiện là đúng nếu iterator có nhiều phần tử hơn hoặc sai khác.


8
Đây là một câu trả lời tuyệt vời nhất. Đối xử với các vòng lặp của bạn giống như một loạt các câu lệnh elif và hành vi khác sẽ phơi bày logic tự nhiên của nó.
Nomenator

1
Tôi cũng thích câu trả lời này, nhưng nó không vẽ một sự tương tự với một loạt các elifcâu lệnh. Có một câu trả lời là có, và nó có một upvote net.
alexis

2
cũng không chính xác, một vòng lặp while có thể có điều kiện đáp ứng Sai ngay trước khi breaks, trong trường hợp đó elsesẽ không chạy nhưng điều kiện là Sai. Tương tự với forcác vòng lặp nó có thể breaktrên phần tử cuối cùng.
Tadhg McDonald-Jensen

36

Tốt hơn nên nghĩ về nó theo cách này: elseKhối sẽ luôn được thực thi nếu mọi thứ đi đúng trong forkhối trước để nó cạn kiệt.

Ngay trong bối cảnh này sẽ có nghĩa là không exception, không break, không return. Bất kỳ tuyên bố nào chiếm quyền điều khiển từ đó forsẽ khiến elsekhối bị bỏ qua.


Một trường hợp sử dụng phổ biến được tìm thấy khi tìm kiếm một mục trong một iterable, trong đó tìm kiếm bị tắt khi tìm thấy mục đó hoặc "not found"cờ được nâng lên / in qua elsekhối sau :

for items in basket:
    if isinstance(item, Egg):
        break
else:
    print("No eggs in basket")  

A continuekhông chiếm quyền điều khiển từ for, vì vậy kiểm soát sẽ tiến hành elsesau khi forhết.


20
Nghe có vẻ rất hay ... nhưng sau đó bạn mong muốn một elseđiều khoản sẽ được thực thi khi mọi thứ không ổn, phải không? Tôi lại bị lẫn lộn lần nữa ...
alexis

Tôi phải không đồng ý với bạn về "Về mặt kỹ thuật, nó không [tương tự về mặt ngữ nghĩa với nhau else]", vì elsenó được chạy khi không có điều kiện nào trong vòng lặp for đánh giá là Đúng, như tôi chứng minh trong câu trả lời của mình
Tadhg McDonald- Jensen

@ TadhgMcDonald-Jensen Bạn cũng có thể phá vỡ vòng lặp trên a False. Vì vậy, câu hỏi làm thế nào forbị hỏng phụ thuộc vào trường hợp sử dụng.
Moses Koledoye

Đúng vậy, tôi đang yêu cầu một cách nào đó liên quan đến những gì xảy ra với nghĩa tiếng Anh của "khác" (điều này thực sự được phản ánh trong các cách sử dụng khác của elsetrăn). Bạn cung cấp một bản tóm tắt trực quan tốt về những gì else, @Moses, nhưng không phải là cách chúng ta có thể liên kết hành vi này với "khác". Nếu một từ khóa khác được sử dụng (ví dụ, nobreaknhư được đề cập trong câu trả lời này cho một câu hỏi liên quan), nó sẽ dễ hiểu hơn.
alexis

1
Nó thực sự không có gì để làm với "mọi thứ sẽ đúng". Cái khác được thực hiện hoàn toàn khi if/ whileđiều kiện ước tính thành false hoặc forhết mục. breaktồn tại vòng lặp chứa (sau else). continuequay lại và đánh giá điều kiện vòng lặp một lần nữa.
Đánh dấu Tolonen

31

Khi nào ifthực hiện một else? Khi điều kiện của nó là sai. Nó hoàn toàn giống nhau cho while/ else. Vì vậy, bạn có thể nghĩ về while/ elsenhư chỉ là một ifđiều kiện tiếp tục chạy tình trạng thực của nó cho đến khi nó đánh giá sai. A breakkhông thay đổi điều đó. Nó chỉ nhảy ra khỏi vòng lặp chứa mà không có đánh giá. Các elsechỉ được thực hiện nếu đánh giá sự if/ whileđiều kiện là sai.

Điều fornày là tương tự, ngoại trừ tình trạng sai của nó đang làm cạn kiệt trình lặp của nó.

continuebreakđừng thực thi else. Đó không phải là chức năng của họ. Các breakthoát vòng lặp chứa. Cáccontinue quay ngược lại phía trên cùng của vòng lặp chứa, nơi điều kiện vòng lặp được đánh giá. Đó là hành động đánh giá if/ whilethành sai (hoặc forkhông có thêm mục nào) thực thi elsevà không có cách nào khác.


1
Những gì bạn nói nghe có vẻ rất hợp lý, nhưng gộp ba điều kiện chấm dứt lại với nhau, "cho đến khi [điều kiện] là Sai hoặc ngắt / tiếp tục", là sai: Điều quan trọng, elsemệnh đề được thực thi nếu vòng lặp được thoát với continue(hoặc bình thường), nhưng không nếu chúng ta thoát với break. Những sự tinh tế này là lý do tại sao tôi đang cố gắng thực sự tìm hiểu những gì elsebắt được và những gì nó không.
alexis

4
@alexis vâng tôi cần làm rõ ở đó. Đã chỉnh sửa. tiếp tục không thực thi cái khác, nhưng trở về đầu vòng lặp mà sau đó có thể đánh giá thành sai.
Đánh dấu Tolonen

24

Đây là những gì nó có nghĩa là:

for/while ...:
    if ...:
        break
if there was a break:
    pass
else:
    ...

Đó là một cách viết đẹp hơn của mẫu phổ biến này:

found = False
for/while ...:
    if ...:
        found = True
        break
if not found:
    ...

Các elsekhoản sẽ không được thực hiện nếu có một returnreturnlá chức năng, vì nó có nghĩa là để. Ngoại lệ duy nhất mà bạn có thể nghĩ đến làfinally , mục đích của nó là đảm bảo rằng nó luôn được thực thi.

continuekhông có gì đặc biệt để làm với vấn đề này. Nó làm cho vòng lặp hiện tại của vòng lặp kết thúc có thể xảy ra để kết thúc toàn bộ vòng lặp, và rõ ràng trong trường hợp đó, vòng lặp không kết thúc bởi mộtbreak .

try/else tương tự

try:
    ...
except:
    ...
if there was an exception:
    pass
else:
    ...

20

Nếu bạn nghĩ rằng các vòng lặp của bạn là một cấu trúc tương tự như thế này (hơi giả mã):

loop:
if condition then

   ... //execute body
   goto loop
else
   ...

nó có thể có ý nghĩa hơn một chút. Một vòng lặp về cơ bản chỉ là một ifcâu lệnh được lặp lại cho đến khi điều kiện là false. Và đây là điểm quan trọng. Vòng lặp kiểm tra tình trạng của nó và thấy rằng nó false, do đó thực thi else(giống như bình thường if/else) và sau đó vòng lặp được thực hiện.

Vì vậy, lưu ý rằng else chỉ nhận được thực hiện khi điều kiện được kiểm tra . Điều đó có nghĩa là nếu bạn thoát khỏi phần thân của vòng lặp ở giữa thực thi với ví dụ a returnhoặc a break, vì điều kiện không được kiểm tra lại, elsetrường hợp sẽ không được thực thi.

Một continuemặt khác dừng việc thực hiện và sau đó nhảy lại để kiểm tra tình trạng của vòng lặp lại, đó là lý do tại sao elsecó thể đạt được trong kịch bản này.


Tôi khá thích câu trả lời này, nhưng bạn có thể đơn giản hóa: Bỏ endnhãn và chỉ cần đặt goto loopbên trong ifcơ thể. Thậm chí có thể lỗi thời bằng cách đặt ifcùng một dòng với nhãn, và nó đột nhiên trông rất giống với chữ gốc.
Bergi

@Bergi Vâng, tôi nghĩ điều đó làm cho nó rõ ràng hơn một chút, cảm ơn.
Keiwan

15

Khoảnh khắc gotcha của tôi với elsemệnh đề của vòng lặp là khi tôi đang xem một cuộc nói chuyện của Raymond Hettinger , người đã kể một câu chuyện về cách anh ấy nghĩ nó nên được gọi nobreak. Hãy xem đoạn mã sau, bạn nghĩ nó sẽ làm gì?

for i in range(10):
    if test(i):
        break
    # ... work with i
nobreak:
    print('Loop completed')

Bạn sẽ đoán nó làm gì? Chà, phần nói nobreaksẽ chỉ được thực thi nếu một breakcâu lệnh không được nhấn trong vòng lặp.


8

Thông thường tôi có xu hướng nghĩ về một cấu trúc vòng lặp như thế này:

for item in my_sequence:
    if logic(item):
        do_something(item)
        break

Rất giống với số lượng if/elifcâu lệnh khác nhau:

if logic(my_seq[0]):
    do_something(my_seq[0])
elif logic(my_seq[1]):
    do_something(my_seq[1])
elif logic(my_seq[2]):
    do_something(my_seq[2])
....
elif logic(my_seq[-1]):
    do_something(my_seq[-1])

Trong trường hợp này, elsecâu lệnh trên vòng lặp for hoạt động chính xác như elsecâu lệnh trên chuỗi elifs, nó chỉ thực thi nếu không có điều kiện nào trước khi nó đánh giá là True. (hoặc ngắt thực thi với returnhoặc một ngoại lệ) Nếu vòng lặp của tôi không phù hợp với đặc điểm kỹ thuật này thường thì tôi chọn từ chối sử dụng for: elsevì lý do chính xác bạn đã đăng câu hỏi này: nó không trực quan.


Đúng. Nhưng một vòng lặp chạy nhiều lần, vì vậy có một chút không rõ ý nghĩa của bạn khi áp dụng điều này cho vòng lặp for. Bạn có thể làm rõ?
alexis

@alexis Tôi đã làm lại câu trả lời của mình, tôi nghĩ bây giờ nó đã rõ ràng hơn rất nhiều.
Tadhg McDonald-Jensen

7

Những người khác đã giải thích các cơ chế của while/for...elsetham chiếu ngôn ngữ Python 3 có định nghĩa có thẩm quyền (xem trong khicho ), nhưng đây là bản ghi nhớ cá nhân của tôi, FWIW. Tôi đoán chìa khóa đối với tôi là chia phần này thành hai phần: một phần để hiểu ý nghĩa của elsemối quan hệ với điều kiện vòng lặp và một phần để hiểu điều khiển vòng lặp.

Tôi thấy dễ dàng nhất để bắt đầu bằng cách hiểu while...else:

whilebạn có nhiều đồ hơn, làm đồ, elsenếu bạn hết, hãy làm cái này

Bản for...elseghi nhớ về cơ bản là giống nhau:

formỗi mục, làm công cụ, nhưng elsenếu bạn hết, làm điều này

Trong cả hai trường hợp, elsephần chỉ đạt được một khi không có thêm mục nào để xử lý và mục cuối cùng đã được xử lý theo cách thông thường (nghĩa là không breakhoặc return). A continuechỉ cần quay lại và xem nếu có thêm mặt hàng. Bản ghi nhớ của tôi cho các quy tắc này áp dụng cho cả hai whilefor:

khi breaking hoặc returning, không có gì elseđể làm
và khi tôi nói continue, đó là "lặp lại để bắt đầu" cho bạn

- với ý nghĩa "loop back to start", rõ ràng, bắt đầu vòng lặp nơi chúng ta kiểm tra xem có thêm mục nào trong vòng lặp không, cho đến khi elsecó liên quan, continuethực sự không có vai trò gì cả.


4
Tôi đề nghị rằng nó có thể được tăng cường bằng cách nói rằng mục đích thông thường của vòng lặp for / other là kiểm tra các mục cho đến khi bạn tìm thấy những gì bạn đang tìm kiếm và muốn dừng lại , hoặc bạn hết các mục. Phần "khác" tồn tại để xử lý phần "bạn hết hàng (mà không tìm thấy thứ bạn đang tìm)".
supercat

@supercat: Có thể, nhưng tôi không biết những công dụng phổ biến nhất hiện có. Cũng elsecó thể được sử dụng để làm một cái gì đó khi bạn hoàn thành đơn giản với tất cả các mục. Các ví dụ bao gồm viết một mục nhật ký, cập nhật giao diện người dùng hoặc báo hiệu một số quy trình khác mà bạn đã hoàn thành. Cái gì đó thật sự. Ngoài ra, một số đoạn mã có trường hợp kết thúc "thành công" với breakbên trong vòng lặp và elseđược sử dụng để xử lý trường hợp "lỗi" khi bạn không tìm thấy mục nào phù hợp trong quá trình lặp (có thể đó là những gì bạn đang nghĩ của?).
Fabian Fagerholm

1
Trường hợp tôi đã nghĩ đến chính xác là trường hợp vụ án thành công kết thúc bằng một "phá vỡ" và "người khác" xử lý sự thiếu thành công. Nếu không có "ngắt" trong một vòng lặp, mã "khác" cũng có thể chỉ đơn giản là đi theo vòng lặp như một phần của khối kèm theo.
supercat

Trừ khi bạn cần phân biệt giữa trường hợp vòng lặp đi qua tất cả các mục lặp mà không bị gián đoạn (và đó là trường hợp thành công) và trường hợp không xảy ra. Sau đó, bạn phải đặt mã "hoàn thiện" trong elsekhối của vòng lặp hoặc theo dõi kết quả bằng các phương tiện khác. Về cơ bản, tôi đồng ý, tôi chỉ nói rằng tôi không biết mọi người sử dụng tính năng này như thế nào và do đó tôi muốn tránh đưa ra các giả định về việc liệu elsekịch bản " xử lý trường hợp thành công" hay kịch bản " elsexử lý trường hợp không thành công" là phổ biến hơn. Nhưng bạn có một điểm tốt, vì vậy bình luận nâng cao!
Fabian Fagerholm

7

Trong phát triển dựa trên thử nghiệm (TDD), khi sử dụng Tiền đề ưu tiên chuyển đổi mô hình , bạn coi các vòng lặp như một khái quát của các câu điều kiện.

Cách tiếp cận này kết hợp tốt với cú pháp này, nếu bạn chỉ xem xét các câu lệnh đơn giản if/else(không elif):

if cond:
    # 1
else:
    # 2

khái quát đến:

while cond:  # <-- generalization
    # 1
else:
    # 2

độc đáo

Trong các ngôn ngữ khác, các bước TDD từ một trường hợp đến các trường hợp có bộ sưu tập đòi hỏi phải tái cấu trúc nhiều hơn.


Đây là một ví dụ từ blog thứ 8 :

Trong bài viết được liên kết tại blog 8light, Word Wrap kata được xem xét: thêm ngắt dòng vào chuỗi ( sbiến trong đoạn trích bên dưới) để làm cho chúng phù hợp với chiều rộng nhất định ( lengthbiến trong đoạn trích bên dưới). Tại một thời điểm, việc triển khai trông như sau (Java):

String result = "";
if (s.length() > length) {
    result = s.substring(0, length) + "\n" + s.substring(length);
} else {
    result = s;
}
return result;

và thử nghiệm tiếp theo, hiện đang thất bại là:

@Test
public void WordLongerThanTwiceLengthShouldBreakTwice() throws Exception {
    assertThat(wrap("verylongword", 4), is("very\nlong\nword"));
    }

Vì vậy, chúng ta có mã hoạt động có điều kiện: khi một điều kiện cụ thể được đáp ứng, ngắt dòng được thêm vào. Chúng tôi muốn cải thiện mã để xử lý nhiều ngắt dòng. Giải pháp được trình bày trong bài viết đề xuất áp dụng phép biến đổi (if-> while) , tuy nhiên tác giả đưa ra nhận xét rằng:

Mặc dù các vòng lặp không thể có elsemệnh đề, vì vậy chúng ta cần loại bỏ elseđường dẫn bằng cách thực hiện ít hơn trong ifđường dẫn. Một lần nữa, đây là một tái cấu trúc.

buộc phải thay đổi mã nhiều hơn trong bối cảnh thử nghiệm thất bại:

String result = "";
while (s.length() > length) {
    result += s.substring(0, length) + "\n";
    s = s.substring(length);
}
result += s;

Trong TDD, chúng tôi muốn viết càng ít mã càng tốt để thực hiện các bài kiểm tra. Nhờ cú pháp của Python, việc chuyển đổi sau là có thể:

từ:

result = ""
if len(s) > length:
    result = s[0:length] + "\n"
    s = s[length:]
else:
    result += s

đến:

result = ""
while len(s) > length:
    result += s[0:length] + "\n"
    s = s[length:]
else:
    result += s

6

Cách tôi nhìn thấy nó, else:kích hoạt khi bạn lặp lại qua cuối vòng lặp.

Nếu bạn breakhoặc returnhoặc raisebạn không lặp quá khứ cuối vòng lặp, bạn ngừng immeadiately, và do đó các else:khối sẽ không chạy. Nếu bạn continuevẫn lặp đi lặp lại qua cuối vòng lặp, vì tiếp tục chỉ bỏ qua bước lặp tiếp theo. Nó không dừng vòng lặp.


1
Tôi thích điều đó, tôi nghĩ rằng bạn đang ở một cái gì đó. Nó liên quan một chút với cách thức vòng lặp được sử dụng để thực hiện trong những ngày cũ tồi tệ trước các từ khóa vòng lặp. (Cụ thể: tấm séc được đặt ở cuối vòng lặp, với gotođỉnh cao là thành công.) Nhưng đó là phiên bản ngắn hơn của câu trả lời được bình chọn hàng đầu ...
alexis

@alexis, chủ quan, nhưng tôi thấy cách thể hiện của tôi dễ nghĩ hơn.
Winston Ewert

thực ra tôi đồng ý Nếu chỉ bởi vì nó tốt hơn.
alexis

4

Hãy nghĩ về elsemệnh đề như là một phần của cấu trúc vòng lặp; breakthoát ra khỏi cấu trúc vòng lặp hoàn toàn, và do đó bỏ qua elsemệnh đề.

Nhưng thực sự, bản đồ tinh thần của tôi chỉ đơn giản là đó là phiên bản 'có cấu trúc' của mẫu C / C ++:

  for (...) {
    ...
    if (test) { goto done; }
    ...
  }
  ...
done:
  ...

Vì vậy, khi tôi gặp for...elsehoặc tự viết nó, thay vì hiểu nó trực tiếp , tôi đã dịch nó thành cách hiểu ở trên về mẫu và sau đó tìm ra phần nào của ánh xạ cú pháp python đến phần nào của mẫu.

(Tôi đặt 'structured' trong các trích dẫn sợ hãi vì sự khác biệt không phải là mã được cấu trúc hay không cấu trúc, mà chỉ là liệu có từ khóa và ngữ pháp dành riêng cho cấu trúc cụ thể không)


1
Đâu là else? Nếu bạn có nghĩa là done:nhãn đứng proxy hoặc else:, tôi tin rằng bạn có nó chính xác ngược.
alexis

@alexis Mã 'khác' sẽ điền vào các '...' ngay trước các done:nhãn. Do đó, sự tương ứng tổng thể là, có thể nói là tốt nhất: Python có cấu trúc else-on-loop để bạn có thể biểu thị mẫu luồng điều khiển này mà không cần goto.
zwol

Có nhiều cách khác để thực hiện mẫu luồng điều khiển này, ví dụ: bằng cách đặt cờ. Đó là những gì elsetránh được.
alexis

2

Nếu bạn kết elsehợp với for, nó có thể gây nhầm lẫn. Tôi không nghĩ rằng từ khóa elselà một lựa chọn tuyệt vời cho cú pháp này, nhưng nếu bạn kết elsehợp với từ khóa ifcó chứa break, bạn có thể thấy nó thực sự có ý nghĩa. elsehầu như không hữu ích nếu không có iftuyên bố trước và tôi tin rằng đây là lý do tại sao người thiết kế cú pháp chọn từ khóa.

Hãy để tôi chứng minh điều đó bằng ngôn ngữ của con người.

formỗi người trong một nhóm nghi phạm ifbất cứ ai là tội phạm breakđiều tra. elsebáo cáo thất bại.


1

Cách tôi nghĩ về nó, chìa khóa là xem xét ý nghĩa của continuehơn là else.

Các từ khóa khác mà bạn đề cập thoát ra khỏi vòng lặp (thoát bất thường) trong khi continue không, nó chỉ bỏ qua phần còn lại của khối mã bên trong vòng lặp. Thực tế là nó có thể đi trước chấm dứt vòng lặp là ngẫu nhiên: việc chấm dứt thực sự được thực hiện theo cách thông thường bằng cách đánh giá biểu thức điều kiện vòng lặp.

Sau đó, bạn chỉ cần nhớ rằng elsemệnh đề được thực thi sau khi chấm dứt vòng lặp bình thường.


0
# tested in Python 3.6.4
def buy_fruit(fruits):
    '''I translate the 'else' below into 'if no break' from for loop '''
    for fruit in fruits:
        if 'rotten' in fruit:
            print(f'do not want to buy {fruit}')
            break
    else:  #if no break
        print(f'ready to buy {fruits}')


if __name__ == '__main__':
    a_bag_of_apples = ['golden delicious', 'honeycrisp', 'rotten mcintosh']
    b_bag_of_apples = ['granny smith', 'red delicious', 'honeycrisp', 'gala', 'fuji']
    buy_fruit(a_bag_of_apples)
    buy_fruit(b_bag_of_apples)

'''
do not want to buy rotten mcintosh
ready to buy ['granny smith', 'red delicious', 'honeycrisp', 'gala', 'fuji']
'''
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.