Domanda

How can you make a 2-shot generator in python?

My attempt (doesn't work):

>>> def g():
...     try:
...         yield 1
...         raise StopIteration('Shot 1 exhausted')
...     finally:
...         yield 2
...         # 'Shot 2 exhausted'
...         
>>> x = g()
>>> list(x), list(x)
([1, 2], [])
# expected output ([1], [2])
È stato utile?

Soluzione

The iterator protocol specifically forbids this:

The intention of the protocol is that once an iterator’s next() method raises StopIteration, it will continue to do so on subsequent calls. Implementations that do not obey this property are deemed broken.

For this reason, the generator syntax does not offer a way to make a 2-shot iterator.

If you really want to do it anyway, you can't use a generator:

class BrokenIterator(object):
    def __init__(self):
        self.callcount = 0
    def __iter__(self):
        return self
    def next(self):
        self.callcount += 1
        if self.callcount == 1:
            return 1
        elif self.callcount == 3:
            return 2
        else:
            raise StopIteration
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top