2016-08-10 13 views
5

Tôi xây dựng một đối tượng có thể lặp lại A chứa danh sách các đối tượng khác B. Tôi muốn có thể tự động bỏ qua một đối tượng cụ thể B trong danh sách nếu nó là bị gắn cờ xấu khi đối tượng A được sử dụng trong vòng lặp for.Làm thế nào để hỏi một iterator trong python mà không thay đổi trạng thái yêu cầu trước của nó

class A(): 
    def __init__(self): 
    self.Blist = [B(1), B(2), B(3)] #where B(2).is_bad() is True, while the other .is_bad() are False 

    def __iter__(self): 
    nextB = iter(self.Blist) 
    #if nextB.next().is_bad(): 
    # return after skip 
    #else: 
    # return nextB 

Tuy nhiên, tôi không thể tìm ra cách để viết các điều kiện được nhận xét trong mã giả ở trên, không được dùng cách lặp hỏi (mệnh đề vẫn thất bại)

Cảm ơn!

+0

Bạn có thể đóng gói các trình vòng lặp của mình trong các đối tượng có hàm 'peek()' và hàm được ghi đè tiếp theo(). Nó phải chứa một biến trạng thái theo dõi cái nào được gọi gần đây nhất, next() hoặc peek(). Nếu next() được gọi sau chính nó, nó sẽ gọi next() trên đối tượng được đóng gói, trả về kết quả và cũng lưu trữ nó trong một bộ đệm. Nếu nó được gọi sau khi một peek() nó sẽ trả về bộ đệm. Peek() luôn gọi encapsulated next(), trả về nó và lưu nó trong buffer(). –

Trả lời

1

Bạn có thể sử dụng một chức năng máy phát điện:

def __iter__(self): 
     for item in self.Blist: 
      if not item.is_bad(): 
       yield item 

Một chức năng máy phát điện được đánh dấu bằng các từ khóa yield. Một hàm máy phát trả về một đối tượng máy phát, là một trình lặp. Nó sẽ đình chỉ thực hiện tại tuyên bố yield và sau đó tiếp tục xử lý khi các cuộc gọi thường gọi next trên interator.

+0

consise và câu trả lời rõ ràng. Cảm ơn! – Pato

+0

Ngoài ra, nó có cần dòng đầu tiên không? vòng lặp có thể đơn giản là 'cho mục trong self.Blist:' – Pato

+0

Bạn nói đúng, nó không cần dòng đầu tiên. Tôi đã sửa đổi câu trả lời của tôi để phản ánh đề xuất của bạn. –

1

Làm thế nào về:

def __iter__(self): 
    nextB = iter(self.Blist) 
    for b_obj in nextB: 
     if b_obj.is_bad(): 
      yield b_obj 

Một ví dụ đơn giản:

class B: 
    def __init__(self, cond): 
     self.cond = cond 

    def is_bad(self): 
     return self.cond 

class A: 
    def __init__(self): 
    self.Blist = [B(True), B(False), B(True)] 

    def __iter__(self): 
    nextB = iter(self.Blist) 
    for b_obj in nextB: 
     if b_obj.is_bad(): 
      yield b_obj 

a = A() 
for x in a: 
    print(x.is_bad()) 

>> True 
    True 
+0

Cảm ơn! Tôi đã chọn tùy chọn Hans là simlpy tốt nhất bởi vì đó là một trong những người bỏ qua B xấu, bạn là đối diện. Nhưng cả hai đều là những gì tôi cần :) – Pato

Các vấn đề liên quan