Can I express this function with a generator?

I have the following function:

def infinite_sequence(starting_value, function):
    value = starting_value
    while True:
        yield value
        value = function(value)

      

Can this be expressed as a generator understanding? If we were dealing with a fixed range and not an infinite sequence, it could be solved like this: (Edit: this is actually wrong)

(function(value) for value in range(start, end))

      

But since we are dealing with an infinite sequence, can we express this using a generator understanding?

+3


source to share


3 answers


You will need some kind of recursive generator expression:

infinite_sequence = itertools.imap(f, itertools.chain(x, __currentgenerator__))

      

where __currentgenerator__

is a hypothetical magic reference to the generator expression in which it appears. (Note that the problem is not that you want an infinite sequence, but that the sequence is defined recursively in terms of itself.)

Unfortunately, Python doesn't have such a feature. Haskell is an example of a language that does because of its lazy argument evaluation:

infinite_sequence = map f x:infinite_sequence

      



However, you can achieve something similar in Python 3 while still using a statement def

by defining a recursive generator.

def infinite_sequence(f, sv):
    x = f(sv)
    yield from itertools.chain(x, infinite_sequence(f, x))

      

( itertools.chain

not strictly necessary, you can use

def inifinite_sequence(f, sv):
    x = f(sv)
    yield x
    yield from infinite_sequence(f, x)

      

but I tried to keep the flavor of Haskell's expression x:infinite_sequence

.)

+1


source


This itertools.accumulate

, ignoring everything but the first value:

from itertools import accumulate, repeat

def function(x): return x*2
start = 1

seq = accumulate(repeat(start), lambda last, _: function(last))

      



Just write it in full.

0


source


Yes, just use an infinite iterator for example itertools.count

.

(function(value) for value in itertools.count(starting_value))

      

-1


source







All Articles