Current value of generator

Question:

In Python I can build a generator like so:

def gen():
    x = range(0, 100)
    for i in x:
        yield i  

I can now define an instance of the generator using:

a = gen()

And pull new values from the generator using

a.next()

But is there a way—a.current()—to get the current value of the generator?

Asked By: Richard

||

Answers:

You set the value of a variable.

current_value = a.next()

then use current_value for all it’s worth.
Python uses this often in for statements

a = xrange(10)
for x in a:
    print(x)

Here you are defining x as the current value of a.

Answered By: Back2Basics

There isn’t such a method, and you cannot add attributes to a generator. A workaround would be to create an iterator object that wraps your generator, and contains a ‘current’ attribute. Taking it an extra step is to use it as a decorator on the generator.

Here’s a utility decorator class which does that:

class with_current(object):

    def __init__(self, generator):
        self.__gen = generator()

    def __iter__(self):
        return self

    def __next__(self):
        self.current = next(self.__gen)
        return self.current

    def __call__(self):
        return self

You can then use it like this:

@with_current
def gen():
    x=range(0,100)
    for i in x:
        yield i

a = gen()

print(next(a))
print(next(a))
print(a.current)

Outputs:

0
1
1
Answered By: Dane White

Using another global variable to store the current value might be feasible.

# Variable that store the current value of the generator
generator_current_val = None

def generator():
    global generator_current_val # to set the current value

    for i in range(10):
        generator_current_val = i
        yield i

a = generator()

print(next(a)) # 0
print(next(a)) # 1
print(next(a)) # 2
print(generator_current_val) # 2
print(next(a)) # 3
Answered By: Tan Kian-teng

You can use a sliding window generator, something like

def _window(i: Iterator[T]) -> Iterator[Tuple[T, Optional[T]]]:
    prev = None
    for x in i:
        if prev:
            yield prev, x
        prev = x
    yield prev, None
i = _window(iter([1,2,3,4]))
print(next(i)) # (1, 2)
print(next(i)) # (2, 3)
print(next(i)) # (3, 4)
print(next(i)) # (4, None)
Answered By: CervEd
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.