Tại sao python sử dụng 'other' sau vòng lặp for và while?


481

Tôi hiểu cách thức hoạt động của công trình này:

for i in range(10):
    print(i)

    if i == 9:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

Nhưng tôi không hiểu tại sao elseđược sử dụng làm từ khóa ở đây, vì nó gợi ý mã được đề cập chỉ chạy nếu forkhối không hoàn thành, điều này trái ngược với những gì nó làm! Cho dù tôi nghĩ về nó như thế nào, bộ não của tôi không thể tiến bộ liền mạch từ fortuyên bố đến elsekhối. Đối với tôi, continuehoặc continuewithsẽ có ý nghĩa hơn (và tôi đang cố gắng rèn luyện bản thân để đọc nó như vậy).

Tôi đang tự hỏi làm thế nào các lập trình viên Python đọc cấu trúc này trong đầu (hoặc lớn tiếng, nếu bạn muốn). Có lẽ tôi đang thiếu một cái gì đó sẽ làm cho các khối mã như vậy dễ giải mã hơn?


26
Bạn có thể muốn dịch nó thành "sau đó" trong đầu.
Marcin

63
Đừng quên dòng khóa trong Zen of Python: "... cách đó ban đầu có thể không rõ ràng trừ khi bạn là người Hà Lan."
Daniel Roseman

51
Trong đầu tôi dịch nó thành "nếu không vỡ" . Và, vì breakđược sử dụng rất nhiều trong các vòng lặp "Tôi đã tìm thấy nó" , bạn có thể dịch nó thành "nếu không tìm thấy" , không xa những gì đã elseđọc
MestreLion

29
Tôi nghĩ rằng câu hỏi thực sự mà nhiều người có ở đây là "Sự khác biệt giữa for ... else foo()và chỉ đặt foo()sau vòng lặp for là gì?" Và câu trả lời là họ hành xử khác nhau chỉ nếu vòng lặp chứa break(như mô tả chi tiết dưới đây).
Sam Kauffman

10
Một dấu chấm phẩy ở trăn ... mắt tôi bị đau .. mặc dù về mặt cú pháp là đúng nhưng thực tế không phải vậy
DarkCygnus

Câu trả lời:


278

Đó là một cấu trúc kỳ lạ ngay cả với các lập trình viên Python dày dạn. Khi được sử dụng cùng với các vòng lặp for, về cơ bản nó có nghĩa là "tìm một số mục trong vòng lặp, nếu không tìm thấy mục nào ...". Như trong:

found_obj = None
for obj in objects:
    if obj.key == search_key:
        found_obj = obj
        break
else:
    print('No object found.')

Nhưng bất cứ khi nào bạn thấy cấu trúc này, một cách khác tốt hơn là đóng gói tìm kiếm trong một hàm:

def find_obj(search_key):
    for obj in objects:
        if obj.key == search_key:
            return obj

Hoặc sử dụng một danh sách hiểu:

matching_objs = [o for o in objects if o.key == search_key]
if matching_objs:
    print('Found {}'.format(matching_objs[0]))
else:
    print('No object found.')

Nó không tương đương về mặt ngữ nghĩa với hai phiên bản còn lại, nhưng hoạt động đủ tốt trong mã quan trọng không hiệu năng trong trường hợp bạn không lặp lại toàn bộ danh sách hay không. Những người khác có thể không đồng ý, nhưng cá nhân tôi sẽ tránh sử dụng các khối for-other hoặc while-other trong mã sản xuất.

Xem thêm [Python-idea] Tóm tắt về ... chủ đề khác


50
Việc hiểu danh sách là sai một lót. Nếu bạn đang tìm kiếm một mục duy nhất, như trong các forví dụ về vòng lặp và muốn sử dụng sự hiểu biết về biểu thức / danh sách của trình tạo, thì bạn muốn next((o for o in objects if o.key == search_key), None)hoặc bọc nó trong một try/ exceptvà không sử dụng giá trị mặc định thay vì if/ else.
agf

4
và giống như câu trả lời của Lance Helsten, có những trường hợp thực tế sử dụng for/elsecấu trúc tốt hơn .
andrean

5
Chúc mừng. Tôi đã có một tập tin bị thụt vào trong đó một elsecặp được ghép với một forvà tôi không biết đó là hợp pháp.
maxywb

3
Tôi nghĩ rằng vòng lặp for là rõ ràng nhất trong các cấu trúc ở đó.
Miles Rout

14
Điều đáng nói là mệnh đề khác sẽ chạy ngay cả khi vòng lặp for có các giá trị trừ khi một breakcâu lệnh được giải thích chạy như trong ví dụ này. Từ các tài liệu ở trên: " elseMệnh đề có một vấn đề nhận thức khác: nếu không có breaktrong vòng lặp, elsemệnh đề này có chức năng dự phòng.". ví dụfor x in [1, 2, 3]:\n print x\n else:\n print 'this executes due to no break'
dhackner

587

Một cấu trúc phổ biến là chạy một vòng lặp cho đến khi tìm thấy một cái gì đó và sau đó thoát ra khỏi vòng lặp. Vấn đề là nếu tôi thoát ra khỏi vòng lặp hoặc vòng lặp kết thúc tôi cần xác định trường hợp nào đã xảy ra. Một phương pháp là tạo một cờ hoặc biến lưu trữ sẽ cho phép tôi thực hiện thử nghiệm thứ hai để xem vòng lặp đã thoát như thế nào.

Ví dụ giả sử rằng tôi cần tìm kiếm trong danh sách và xử lý từng mục cho đến khi tìm thấy mục cờ và sau đó dừng xử lý. Nếu mục cờ bị thiếu thì cần phải có ngoại lệ.

Sử dụng Python for... elsexây dựng bạn có

for i in mylist:
    if i == theflag:
        break
    process(i)
else:
    raise ValueError("List argument missing terminal flag.")

So sánh điều này với một phương pháp không sử dụng đường cú pháp này:

flagfound = False
for i in mylist:
    if i == theflag:
        flagfound = True
        break
    process(i)

if not flagfound:
    raise ValueError("List argument missing terminal flag.")

Trong trường hợp đầu tiên, raisenó được liên kết chặt chẽ với vòng lặp for mà nó hoạt động. Trong lần thứ hai, ràng buộc không mạnh và lỗi có thể được đưa ra trong quá trình bảo trì.


69
Điều này giải thích nó tốt hơn câu trả lời được chọn trong đó tác giả không thực sự hiểu được điều gì khác!
erikbwork

17
Tôi phải nói rằng đường cú pháp này có thể làm thối răng dự án của bạn. Điều này sẽ không làm cho một Python: the good partscuốn sách.
thuyền viên

1
Bạn có thể xác nhận rằng trong ví dụ của bạn, process(i)xảy ra cho mọi mục mylisthoàn toàn trước đây theflag, và không xảy ra với theflagchính nó không? Có phải đó là những gì đã được dự định?
bli

4
processsẽ thực thi trên từng icái tồn tại trong danh sách trước khi theflagđạt được, nó sẽ không được thực thi trên các phần tử trong danh sách sau theflagvà nó sẽ không được thực thi trên theflag.
Lance Helsten 11/03/2015

1
câu lệnh khác cũng được thực thi nếu iterable không có phần tử
Mất Crotchet

173

Có một bài thuyết trình tuyệt vời của Raymond Hettinger, có tiêu đề Biến đổi mã thành Python đẹp, thành ngữ , trong đó ông nói ngắn gọn về lịch sử của for ... elsecông trình. Phần có liên quan là "Phân biệt nhiều điểm thoát trong các vòng lặp" bắt đầu từ 15:50 và tiếp tục trong khoảng ba phút. Dưới đây là những điểm cao:

  • Cấu for ... elsetrúc được Donald Knuth nghĩ ra để thay thế cho một số GOTOtrường hợp sử dụng nhất định ;
  • Việc sử dụng lại elsetừ khóa có ý nghĩa bởi vì "đó là những gì Knuth đã sử dụng và mọi người biết, vào thời điểm đó, tất cả [các fortuyên bố] đã nhúng một ifGOTObên dưới, và họ mong đợi else;"
  • Nhìn nhận lại, nó nên được gọi là "không phá vỡ" (hoặc có thể là "quý tộc"), và sau đó nó sẽ không gây nhầm lẫn. *

Vì vậy, nếu câu hỏi là "Tại sao họ không thay đổi từ khóa này?" sau đó Cat Plus Plus có thể đã đưa ra câu trả lời chính xác nhất - tại thời điểm này, nó sẽ quá phá hủy đối với mã hiện tại là không thực tế. Nhưng nếu câu hỏi bạn thực sự hỏi là tại sao lại elseđược sử dụng lại ngay từ đầu, thì rõ ràng nó có vẻ như là một ý tưởng tốt vào thời điểm đó.

Cá nhân, tôi thích sự thỏa hiệp của việc bình luận nội # no breaktuyến ở bất cứ nơi nào elsecó thể bị nhầm lẫn, trong nháy mắt, như thuộc về vòng lặp. Nó hợp lý rõ ràng và súc tích. Tùy chọn này được đề cập ngắn gọn trong bản tóm tắt mà Bjorn liên kết ở cuối câu trả lời của anh ấy:

Để đầy đủ, tôi nên đề cập rằng với một chút thay đổi trong cú pháp, các lập trình viên muốn cú pháp này có thể có nó ngay bây giờ:

for item in sequence:
    process(item)
else:  # no break
    suite

* Trích dẫn phần thưởng từ phần đó của video: "Giống như nếu chúng ta gọi hàm lambda , không ai sẽ hỏi, 'Lambda làm gì?'"


33

Bởi vì họ không muốn giới thiệu một từ khóa mới cho ngôn ngữ. Mỗi cái đánh cắp một mã định danh và gây ra các vấn đề tương thích ngược, vì vậy nó thường là giải pháp cuối cùng.


2
Có vẻ như finallysẽ là một lựa chọn tốt hơn trong trường hợp đó. Là từ khóa cuối cùng chưa xuất hiện tại thời điểm cấu trúc này được giới thiệu?
Ponkadoodle

26
@Wallacoloo finallykhông tốt hơn nhiều, bởi vì nó ngụ ý rằng khối sẽ luôn được thực thi sau vòng lặp, và nó không (vì điều đó là dư thừa khi chỉ cần đặt mã để chạy sau vòng lặp).
Cat Plus Plus

Cũng không thể finallyvì mệnh đề khác cũng được thực thi khi continueđược sử dụng trong vòng lặp for - điều đó có thể nhiều lần và không chỉ ở cuối.
pepr

6
Việc elsethực thi mệnh đề @pepr không bị ảnh hưởng bởi continue( tài liệumã kiểm tra )
Air

@AirThomas: +1. Bạn đúng rồi. Việc elsenày chỉ được thực hiện khi continuelà lần lặp lại cuối cùng.
pepr

33

Để làm cho nó đơn giản, bạn có thể nghĩ về nó như thế;

  • Nếu nó gặp breaklệnh trong forvòng lặp, elsephần sẽ không được gọi.
  • Nếu nó không gặp breaklệnh trong forvòng lặp, elsephần sẽ được gọi.

Nói cách khác, nếu vòng lặp lặp không bị "hỏng" break, elsephần sẽ được gọi.


Các elsekhối cũng sẽ không được thực hiện nếu cơ thể của vòng lặp đặt ra một ngoại lệ.
Amal K

17

Cách dễ nhất mà tôi tìm thấy để 'hiểu' những gì mà người khác đã làm, và quan trọng hơn, khi sử dụng nó, là tập trung vào nơi tuyên bố phá vỡ nhảy tới. Cấu trúc For / other là một khối đơn. Sự phá vỡ nhảy ra khỏi khối, và do đó nhảy 'hơn' mệnh đề khác. Nếu nội dung của mệnh đề khác chỉ đơn giản tuân theo mệnh đề for, nó sẽ không bao giờ bị nhảy qua, và do đó logic tương đương sẽ phải được cung cấp bằng cách đặt nó vào trong if. Điều này đã được nói trước đây, nhưng không hoàn toàn bằng những từ này, vì vậy nó có thể giúp đỡ người khác. Hãy thử chạy đoạn mã sau. Tôi hoàn toàn ủng hộ nhận xét 'không nghỉ ngơi' cho rõ ràng.

for a in range(3):
    print(a)
    if a==4: # change value to force break or not
        break
else: #no break  +10 for whoever thought of this decoration
    print('for completed OK')

print('statement after for loop')

"Sự phá vỡ nhảy ra khỏi khối, và do đó nhảy 'mệnh đề khác' - trong khi điều này có thể hữu ích như một cách" nhận " for:/ else:, nó không thực sự cung cấp một lời biện minh cho từ khóa else. Với khung được đưa ra ở đây, then:có vẻ như nó sẽ tự nhiên hơn nhiều. (Có nhiều lý do để elseđược chọn, được đưa ra trong các câu trả lời khác - chúng chỉ không được cung cấp ở đây.)
Mark Amery

16

Tôi nghĩ rằng tài liệu có một lời giải thích tuyệt vời khác , tiếp tục

[...] Nó được thực thi khi vòng lặp kết thúc thông qua việc cạn kiệt danh sách (với for) hoặc khi điều kiện trở thành sai (với while), nhưng không phải khi vòng lặp bị chấm dứt bởi câu lệnh break. "

Nguồn: Tài liệu Python 2: Hướng dẫn về luồng điều khiển


13

Tôi đọc nó một cái gì đó như:

Nếu vẫn còn điều kiện để chạy vòng lặp, làm công cụ, khác làm điều khác.


Các điều kiện của bạn vẫn hữu ích (+1) mặc dù điều đó là sai - đó là con người ;-)
Wolf

-1; cách phát âm này của for:/ else:làm cho âm thanh giống như ý else:chí luôn chạy sau vòng lặp, không phải vậy.
Đánh dấu Amery

11

Vì phần kỹ thuật đã được trả lời khá nhiều, nhận xét của tôi chỉ liên quan đến sự nhầm lẫn tạo ra từ khóa tái chế này .

Là Python một ngôn ngữ lập trình rất hùng hồn , việc sử dụng sai từ khóa còn khét tiếng hơn. Các elsetừ khóa một cách hoàn hảo mô tả một phần của dòng chảy của một cây quyết định, "nếu bạn không thể làm được điều này, (khác) làm được điều đó". Nó ngụ ý trong ngôn ngữ của chúng ta.

Thay vào đó, sử dụng từ khóa này với whilevà các forcâu lệnh tạo ra sự nhầm lẫn. Lý do, sự nghiệp của chúng tôi là lập trình viên đã dạy chúng tôi rằng elsetuyên bố nằm trong một cây quyết định; phạm vi logic của nó , một trình bao bọc có điều kiện trả về một đường dẫn để theo dõi. Trong khi đó, các câu lệnh lặp có một mục tiêu rõ ràng theo nghĩa bóng để đạt được một cái gì đó. Mục tiêu được đáp ứng sau các lần lặp lại liên tục của một quá trình.

if / else chỉ ra một con đường để làm theo . Vòng lặp đi theo một con đường cho đến khi "mục tiêu" được hoàn thành .

Vấn đề là đó elselà một từ xác định rõ ràng tùy chọn cuối cùng trong một điều kiện. Các ngữ nghĩa của từ này đều được chia sẻ bởi Python và Ngôn ngữ loài người. Nhưng từ khác trong Ngôn ngữ của con người không bao giờ được sử dụng để chỉ hành động mà ai đó hoặc một cái gì đó sẽ thực hiện sau khi một cái gì đó được hoàn thành. Nó sẽ được sử dụng nếu trong quá trình hoàn thành nó, một vấn đề tăng lên (giống như một tuyên bố phá vỡ ).

Cuối cùng, từ khóa sẽ vẫn còn trong Python. Rõ ràng đó là sai lầm, rõ ràng hơn khi mọi lập trình viên cố gắng đưa ra một câu chuyện để hiểu cách sử dụng của nó giống như một số thiết bị ghi nhớ. Tôi đã yêu nếu họ đã chọn thay vì từ khóa then. Tôi tin rằng từ khóa này phù hợp hoàn hảo trong dòng lặp đó, phần thưởng sau vòng lặp.

Nó giống với tình huống mà một đứa trẻ có sau khi thực hiện từng bước trong việc lắp ráp một món đồ chơi: Và THÌ bố gì?


Tôi nghĩ rằng câu trả lời này giải quyết vấn đề nhầm lẫn Tôi nghĩ rằng OP đang nói về. Từ khóa khác hoàn toàn ngược lại với những gì bạn mong đợi từ nghĩa tiếng Anh của từ khác khi được gắn với hành động của for. Về lý thuyết, for ... other có thể hoạt động khác ở chỗ bạn kết thúc ở phần khác khi vòng lặp bị hỏng, nhưng vấn đề là sử dụng nó để tìm phần tử x và xử lý trường hợp x không tìm thấy, bạn có thể phải sử dụng cờ hoặc thử nghiệm khác sau toàn bộ cho .. cấu trúc khác
Spacen Jasset

7

Tôi đọc nó như "Khi iterablehết hoàn toàn và việc thực thi sắp được chuyển sang câu lệnh tiếp theo sau khi hoàn thành formệnh đề khác, mệnh đề khác sẽ được thực thi." Do đó, khi phép lặp bị phá vỡ break, điều này sẽ không được thực thi.


6

Tôi đồng ý, nó giống như một 'elif không [điều kiện nâng cao phá vỡ]'.

Tôi biết đây là một chủ đề cũ, nhưng tôi đang xem xét cùng một câu hỏi ngay bây giờ và tôi không chắc ai đã nắm bắt được câu trả lời cho câu hỏi này theo cách tôi hiểu.

Đối với tôi, có ba cách để "đọc" các elsetrong For... elsehoặc While... elsebáo cáo, tất cả trong số đó là tương đương, bao gồm:

  1. else == if the loop completes normally (without a break or error)
  2. else == if the loop does not encounter a break
  3. else == else not (condition raising break) (có lẽ có một điều kiện như vậy, hoặc bạn sẽ không có một vòng lặp)

Vì vậy, về cơ bản, "cái khác" trong một vòng lặp thực sự là "elif ..." trong đó '...' là (1) không nghỉ, tương đương với (2) KHÔNG [điều kiện nâng cao phá vỡ].

Tôi nghĩ điều quan trọng là điều đó elselà vô nghĩa nếu không có 'phá vỡ', do đó, for...elsebao gồm:

for:
    do stuff
    conditional break # implied by else
else not break:
    do more stuff

Vì vậy, các yếu tố thiết yếu của một for...elsevòng lặp như sau và bạn sẽ đọc chúng bằng tiếng Anh đơn giản như:

for:
    do stuff
    condition:
        break
else: # read as "else not break" or "else not condition"
    do more stuff

Như các áp phích khác đã nói, một sự phá vỡ thường được nêu ra khi bạn có thể xác định vị trí mà vòng lặp của bạn đang tìm kiếm, do đó else:trở thành "phải làm gì nếu mục tiêu không được định vị".

Thí dụ

Bạn cũng có thể sử dụng xử lý ngoại lệ, ngắt và cho các vòng lặp cùng nhau.

for x in range(0,3):
    print("x: {}".format(x))
    if x == 2:
        try:
            raise AssertionError("ASSERTION ERROR: x is {}".format(x))
        except:
            print(AssertionError("ASSERTION ERROR: x is {}".format(x)))
            break
else:
    print("X loop complete without error")

Kết quả

x: 0
x: 1
x: 2
ASSERTION ERROR: x is 2
----------
# loop not completed (hit break), so else didn't run

Thí dụ

Ví dụ đơn giản với một phá vỡ được nhấn.

for y in range(0,3):
    print("y: {}".format(y))
    if y == 2: # will be executed
        print("BREAK: y is {}\n----------".format(y))
        break
else: # not executed because break is hit
    print("y_loop completed without break----------\n")

Kết quả

y: 0
y: 1
y: 2
BREAK: y is 2
----------
# loop not completed (hit break), so else didn't run

Thí dụ

Ví dụ đơn giản khi không có nghỉ, không có điều kiện nâng cao thời gian nghỉ và không gặp lỗi.

for z in range(0,3):
     print("z: {}".format(z))
     if z == 4: # will not be executed
         print("BREAK: z is {}\n".format(y))
         break
     if z == 4: # will not be executed
         raise AssertionError("ASSERTION ERROR: x is {}".format(x))
else:
     print("z_loop complete without break or error\n----------\n")

Kết quả

z: 0
z: 1
z: 2
z_loop complete without break or error
----------

6

Các elsetừ khóa có thể gây nhầm lẫn ở đây, và càng nhiều người có ra nhọn, một cái gì đó giống như nobreak, notbreaklà thích hợp hơn.

Để hiểu một for ... else ...cách logic, hãy so sánh nó với try...except...else, không if...else..., hầu hết các lập trình viên python đều quen thuộc với đoạn mã sau:

try:
    do_something()
except:
    print("Error happened.") # The try block threw an exception
else:
    print("Everything is find.") # The try block does things just find.

Tương tự, hãy nghĩ về breakmột loại đặc biệt Exception:

for x in iterable:
    do_something(x)
except break:
    pass # Implied by Python's loop semantics
else:
    print('no break encountered')  # No break statement was encountered

Sự khác biệt là pythonngụ ý except breakvà bạn không thể viết nó ra, vì vậy nó trở thành:

for x in iterable:
    do_something(x)
else:
    print('no break encountered')  # No break statement was encountered

Vâng, tôi biết so sánh này có thể khó khăn và mệt mỏi, nhưng nó làm rõ sự nhầm lẫn.


Bạn nên tạo một liên kết đến tài nguyên khi bạn sao chép từ nó: Ghi chú Python của Nick Coghlan .
godaygo

@godaygo cảm ơn vì đường link. Tôi đã đọc và chấp nhận khái niệm này khi lần đầu tiên học python, đã không ghi nhớ nguồn khi viết câu trả lời.
cizixs

@cizixs Bạn "không ghi nhớ nguồn" mà chỉ tình cờ bao gồm toàn bộ câu bình luận giống hệt với bản gốc? Ôi trời ơi.
Mark Amery

5

Các mã trong elsekhối lệnh sẽ được thực thi khi forvòng lặp không bị phá vỡ.

for x in xrange(1,5):
    if x == 5:
        print 'find 5'
        break
else:
    print 'can not find 5!'
#can not find 5!

Từ các tài liệu: phá vỡ và tiếp tục Tuyên bố, và các điều khoản khác về Vòng lặp

Các câu lệnh lặp có thể có một mệnh đề khác; nó được thực thi khi vòng lặp kết thúc thông qua sự cạn kiệt của danh sách (với for) hoặc khi điều kiện trở thành sai (với while), nhưng không phải khi vòng lặp bị chấm dứt bởi câu lệnh break. Điều này được minh họa bằng vòng lặp sau, tìm kiếm các số nguyên tố:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(Có, đây là mã chính xác. Hãy nhìn kỹ: mệnh đề khác thuộc về vòng lặp for, không phải câu lệnh if.)

Khi được sử dụng với một vòng lặp, mệnh đề khác có nhiều điểm chung với mệnh đề khác của câu lệnh try so với mệnh đề if: mệnh đề khác của câu lệnh try chạy khi không có ngoại lệ xảy ra và mệnh đề khác của vòng lặp chạy khi không xảy ra ngắt . Để biết thêm về tuyên bố thử và ngoại lệ, hãy xem Xử lý ngoại lệ.

Câu lệnh continue, cũng được mượn từ C, tiếp tục với lần lặp tiếp theo của vòng lặp:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

1
Điều này không thêm gì và không trả lời câu hỏi, không phải như thế nào mà là tại sao .
Không khí

5

Đây là một cách nghĩ về nó mà tôi chưa thấy ai khác đề cập ở trên:

Đầu tiên, hãy nhớ rằng vòng lặp for về cơ bản chỉ là đường cú pháp xung quanh vòng lặp while. Ví dụ: vòng lặp

for item in sequence:
    do_something(item)

có thể được viết lại (khoảng) như

item = None
while sequence.hasnext():
    item = sequence.next()
    do_something(item)

Thứ hai, hãy nhớ rằng các vòng lặp while về cơ bản chỉ là các khối if lặp lại! Bạn luôn có thể đọc một vòng lặp while là "nếu điều kiện này là đúng, hãy thực thi phần thân, sau đó quay lại và kiểm tra lại".

Vì vậy, while / other có ý nghĩa hoàn hảo: Đó là cấu trúc chính xác giống như / if, với chức năng lặp được thêm vào cho đến khi điều kiện trở thành sai thay vì chỉ kiểm tra điều kiện một lần.

Và sau đó, for / other cũng có ý nghĩa hoàn hảo: bởi vì tất cả các vòng lặp chỉ là đường cú pháp trên đầu vòng lặp, bạn chỉ cần tìm ra điều kiện ngầm của vòng lặp while là gì, và sau đó cái kia tương ứng với điều đó khi nào điều kiện trở thành sai.


4

Câu trả lời tuyệt vời là:

  • điều này giải thích lịch sử, và
  • điều này đưa ra trích dẫn đúng để dễ dàng dịch / hiểu của bạn.

Lưu ý của tôi ở đây xuất phát từ những gì Donald Knuth từng nói (xin lỗi không thể tìm thấy tài liệu tham khảo) rằng có một cấu trúc trong khi khác không thể phân biệt được với if-other, cụ thể là (trong Python):

x = 2
while x > 3:
    print("foo")
    break
else:
    print("boo")

có cùng lưu lượng (không bao gồm chênh lệch mức thấp) như:

x = 2
if x > 3:
    print("foo")
else:
    print("boo")

Vấn đề là if-other có thể được coi là đường cú pháp trong khi-other đã ẩn breakở cuối ifkhối của nó . Hàm ý ngược lại, whilevòng lặp đó là phần mở rộng if, phổ biến hơn (nó chỉ lặp lại / kiểm tra điều kiện lặp), bởi vì ifthường được dạy trước đây while. Tuy nhiên điều đó không đúng bởi vì điều đó có nghĩa là elsechặn trong khi khác sẽ được thực thi mỗi lần khi điều kiện sai.

Để giảm bớt sự hiểu biết của bạn nghĩ về nó theo cách đó:

Không có break, returnv.v., vòng lặp chỉ kết thúc khi điều kiện không còn đúng nữa và trong trường hợp đó, elsekhối cũng sẽ thực thi một lần. Trong trường hợp Python, forbạn phải xem xét forcác vòng lặp kiểu C (có điều kiện) hoặc dịch chúng sang while.

Một lưu ý khác:

Vòng lặp sớm break, returnv.v ... bên trong vòng lặp làm cho điều kiện không thể trở thành sai vì thực thi đã nhảy ra khỏi vòng lặp trong khi điều kiện là đúng và nó sẽ không bao giờ quay lại để kiểm tra lại.


3

Bạn có thể nghĩ về nó như, elsenhư trong phần còn lại của công cụ, hoặc những thứ khác, điều đó không được thực hiện trong vòng lặp.


3
for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
else:
    print("Completed successfully")

"khác" ở đây là đơn giản điên cuồng, chỉ có nghĩa là

1, "nếu for clauseđược hoàn thành"

for i in range(3):
    print(i)

    if i == 2:
        print("Too big - I'm giving up!")
        break;
if "for clause is completed":
    print("Completed successfully")

Nó được sử dụng để viết các câu lệnh dài như "mệnh đề đã hoàn thành", vì vậy họ giới thiệu "khác".

else đây là một nếu trong bản chất của nó.

2, Tuy nhiên, làm thế nào về for clause is not run at all

In [331]: for i in range(0):
     ...:     print(i)
     ...: 
     ...:     if i == 9:
     ...:         print("Too big - I'm giving up!")
     ...:         break
     ...: else:
     ...:     print("Completed successfully")
     ...:     
Completed successfully

Vì vậy, tuyên bố hoàn toàn của nó là sự kết hợp logic:

if "for clause is completed" or "not run at all":
     do else stuff

hoặc đặt nó theo cách này:

if "for clause is not partially run":
    do else stuff

hoặc theo cách này:

if "for clause not encounter a break":
    do else stuff

khác hoạt động như "giao dịch" trong SQL.
Giải tích

2

Đây là một trường hợp sử dụng thành ngữ khác bên cạnh tìm kiếm. Giả sử bạn muốn đợi một điều kiện là đúng, ví dụ: một cổng sẽ được mở trên một máy chủ từ xa, cùng với một số thời gian chờ. Sau đó, bạn có thể sử dụng một while...elsecấu trúc như vậy:

import socket
import time

sock = socket.socket()
timeout = time.time() + 15
while time.time() < timeout:
    if sock.connect_ex(('127.0.0.1', 80)) is 0:
        print('Port is open now!')
        break
    print('Still waiting...')
else:
    raise TimeoutError()

1

Tôi chỉ cố gắng để có ý nghĩa của nó một lần nữa bản thân mình. Tôi thấy rằng những điều sau đây giúp!

• Hãy nghĩ về việc elseđược ghép nối với ifbên trong vòng lặp (thay vì với for) - nếu điều kiện được đáp ứng thì phá vỡ vòng lặp, hãy làm điều này - ngoại trừ một điều kiện elseđược ghép nối với nhiều ifs!
• Nếu không có ifs nào hài lòng, thì hãy làm else.
• Nhiều ifs thực sự cũng có thể được coi là if- elifs!


-2

Tôi coi cấu trúc như là (nếu) A khác B và for (if) -else là một if- other , đại khái . Nó có thể giúp để hiểu khác .

A và B được thực thi nhiều nhất một lần, giống như cấu trúc if-other.

for (if) có thể được coi là một if đặc biệt, trong đó có một vòng lặp để cố gắng đáp ứng điều kiện if. Khi điều kiện if được đáp ứng, A và phá vỡ ; Khác , B.


-2

Python sử dụng một vòng lặp khác sau vòng lặp for và while để nếu không có gì áp dụng cho vòng lặp, điều gì đó sẽ xảy ra. Ví dụ:

test = 3
while test == 4:
     print("Hello")
else:
     print("Hi")

Đầu ra sẽ là 'Hi' nhiều lần (nếu tôi đúng).

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.