2011-12-07 24 views
12

Gần đây tôi đã đọc this question có giải pháp về các vòng ghi nhãn trong Java.Vòng đặt tên bằng Python

Tôi tự hỏi nếu hệ thống đặt tên vòng lặp như vậy tồn tại trong Python hay không. Tôi đã ở trong một tình huống nhiều lần mà tôi cần phải thoát ra khỏi một vòng ngoài for từ một vòng lặp bên trong for. Thông thường, tôi giải quyết vấn đề này bằng cách đặt vòng lặp bên trong trong một hàm trả về (trong số những người khác) một boolean được sử dụng như một điều kiện phá vỡ. Nhưng các vòng ghi nhãn để phá vỡ có vẻ đơn giản hơn rất nhiều và tôi muốn thử điều đó, nếu chức năng như vậy tồn tại trong python

Có ai biết không?

+0

Kiểm tra [câu trả lời thứ hai] (http://stackoverflow.com/questions/653509/breaking-out-of-nested-loops), hopefull y nó giúp một số. Nhưng từ những gì tôi có thể thấy, không có hệ thống như vậy tồn tại. –

+0

"Nhưng các vòng ghi nhãn để phá vỡ có vẻ đơn giản hơn nhiều"? Đơn giản hơn các chức năng phù hợp? Làm thế nào? Bạn có thể cung cấp một số bằng chứng về việc làm thế nào điều này sẽ được "đơn giản"? –

+1

Tôi không có một ví dụ hữu ích, nhưng nó sẽ là một tình huống mà tôi sẽ phải tạo ra một chức năng mà sẽ được sử dụng chỉ trong một chỗ. Có lẽ "đơn giản" là từ sai. Điều tôi muốn nói là tôi sẽ không phải định nghĩa một chức năng mới chỉ để sử dụng tại điểm ONE đó. – inspectorG4dget

Trả lời

9

Có đề xuất bao gồm các vòng được đặt tên trong trăn PEP3136, tuy nhiên, nó đã bị từ chối với giải thích here. Sự từ chối chủ yếu là do số lượng hiếm hoi các trường hợp mà khả năng đọc mã sẽ được cải thiện bằng cách bao gồm cấu trúc này.

1

Không.

Tùy thuộc vào những gì bạn đang làm, có cơ hội tốt để bạn có thể sử dụng thứ gì đó từ itertools để làm phẳng vòng lặp lồng nhau của bạn thành một vòng lặp đơn.

8

Mặc dù có nhiều lý do để bao gồm việc đặt tên theo vòng lặp trong cấu trúc ngôn ngữ, bạn có thể dễ dàng tránh nó trong python mà không mất khả năng đọc. An thực hiện các ví dụ được đề cập trong python

>>> try: 
    for i in xrange(0,5): 
     for j in xrange(0,6): 
      if i*j > 6: 
       print "Breaking" 
       raise StopIteration 
      print i," ",j 
except StopIteration: 
    print "Done" 


0 0 
0 1 
0 2 
0 3 
0 4 
0 5 
1 0 
1 1 
1 2 
1 3 
1 4 
1 5 
2 0 
2 1 
2 2 
2 3 
Breaking 
Done 
>>> 

tôi giải quyết vấn đề này bằng cách đặt vòng lặp bên trong một hàm lợi nhuận (trong số những người khác) một boolean được sử dụng như một tình trạng vi phạm.

Tôi nghĩ bạn nên thử điều này. Điều này là rất pythonic, đơn giản và dễ đọc.

+2

+1. Sử dụng các ngoại lệ cho điều khiển luồng là hoàn toàn độc hại trong Python, mặc dù nó được coi là kiểu xấu trong các ngôn ngữ khác, thường là vì lý do hiệu suất. – kindall

+2

Điều gì xảy ra nếu tôi chỉ muốn "tiếp tục" vòng lặp bên ngoài, thay vì dừng nó? – Guillochon

+1

@Guillochon Chỉ cần đặt câu lệnh thử trong vòng đầu tiên cho vòng lặp – Dylanthepiguy

6

Đây là một cách để thoát ra khỏi nhiều, khối lồng nhau sử dụng một trình quản lý nội dung:

import contextlib 

@contextlib.contextmanager 
def escapable(): 
    class Escape(RuntimeError): pass 
    class Unblock(object): 
     def escape(self): 
      raise Escape() 

    try: 
     yield Unblock() 
    except Escape: 
     pass 

Bạn có thể sử dụng nó để thoát ra khỏi nhiều vòng:

with escapable() as a: 
    for i in xrange(30): 
     for j in xrange(30): 
      if i * j > 6: 
       a.escape() 

Và bạn thậm chí có thể làm tổ chúng:

with escapable() as a: 
    for i in xrange(30): 
     with escapable() as b: 
      for j in xrange(30): 
       if i * j == 12: 
        b.escape() # Break partway out 
       if i * j == 40: 
        a.escape() # Break all the way out 
Các vấn đề liên quan