Pato
Pato

Reputation: 113

how to inquire an iterator in python without changing its pre-inquire state

I built an iterable object A that holds a list of other objects B. I want to be able to automatically skip a particular object B on the list if it is flagged bad when the object A is used in a for loop.

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

However, I cannot figure out how to write the conditional that is commented in pseudo code above, without skipping the iteration inquired (the else clause fails)

Thanks!

Upvotes: 5

Views: 105

Answers (2)

Hans Then
Hans Then

Reputation: 11322

You can use a generator function:

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

A generator function is marked by the keyword yield. A generator function returns a generator object, which is an iterator. It will suspend execution at the yield statement and then resume processing when the calling routine calls next on the interator.

Upvotes: 1

DeepSpace
DeepSpace

Reputation: 81654

How about:

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

A simplified example:

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

Upvotes: 1

Related Questions