Q:

python generator endless stream without using yield

i'm trying to generate an endless stream of results given a function f and an initial value x
so first call should give the initial value, second call should give f(x), third call is f(x2) while x2 is the previous result of f(x) and so on..
what i have come up with:
def generate(f, x): 
   return itertools.repeat(lambda x: f(x))

which does not  seem to work. any ideas? (i cant use yield in my code). also i cant use more than 1 line of code for this problem. any help would be appreciated.
also note that in a previous ex. i was asked to use the yield. with no problems:
while True:
    yield x
    x = f(x)

this works fine. but now.. no clue how to do it without

A:

In Python 3.3, you can use itertools.accumulate:
import itertools

def generate(f, x):
  return itertools.accumulate(itertools.repeat(x), lambda v,_:f(v))

for i, val in enumerate(generate(lambda x: 2*x, 3)):
  print(val)
  if i == 10:
    break

A:

I think this works:
import itertools as it
def g(f, x):
    return it.chain([x],(setattr(g, 'x', f(getattr(g, 'x', x))) or getattr(g, 'x') for _ in it.count()))

def f(x):
    return x + 1

gen = g(f, 1)
print next(gen)
print next(gen)
print next(gen)
print next(gen)

Of course, it relys on some sketchy behavior where I actually add an attribute to the function itself to keep the state.  Basically, this function will only work the first time you call it.  After that, all bets are off.
If we want to relax that restriction, we can use a temporary namespace.  The problem is that to get a temporary namespace we need a unique class instance (or class, but an instance is cleaner and only requires 1 extra set of parenthesis).  To make that happen in one line, we need to create a new function inline and use that as a default argument:
import itertools as it
def g(f, x):
    return (lambda f, x, ns=type('foo', (object,), {})(): \
        it.chain([x], 
                 (setattr(ns, 'x', f(getattr(ns, 'x', x))) or getattr(ns, 'x') 
                          for _ in it.count()))
            )(f, x)

def f(x):
    return x + 1

gen = g(f, 1)
print next(gen) == 1
print next(gen) == 2
print next(gen) == 3
print next(gen) == 4

print "first worked?"
gen2 = g(f, 2)
print next(gen2) == 2
print next(gen2) == 3
print next(gen2) == 4

I've broken it into a few lines, for readability, but it's a 1-liner at heart.
A version without any imports
(and the most robust one yet I believe).
def g(f, x):
    return iter(lambda f=f, x=x, ns=type('foo', (object,), {'x':x}): ((getattr(ns, 'x'),setattr(ns, 'x', f(getattr(ns, 'x'))))[0]), object())

One trick here is the same as before.  We create a lambda function with a mutable default argument to keep the state.  Inside the function, we build a tuple.  The first item is what we actually want, the second item is the return value of the setattr function which is used to update the state.  In order to get rid of the itertools.chain, we set the initial value on the namespace to the value of x so the class is already initialzed to have the starting state.  The second trick is that we use the two argument form of iter to get rid of it.count() which was only used to create an infinite iterable before.  iter keeps calling the function you give it as the first argument until the return value is equal to the second argument.  However, since my second argument is an instance of object, nothing returned from our function will ever be equal to it so we've effectively created an infinite iterable without itertools or yield!  Come to think of it, I believe this last version is the most robust too.  Previous versions had a bug where they relied on the truthfulness of the return value of f.  I think they might have failed if f returned 0.  This last version fixes that bug.

