It will be based on iterate from Haskell.
iterate :: (a -> a) -> a -> [a]
iterate fx returns an endless list of repeating applications f - x :
iterate fx == [x, fx, f (fx), ...]
In Python:
def iterate(f, x): while True: yield x x = f(x)
Usage example:
>>> import itertools.islice >>> def take(n, iterable): ... return list(islice(iterable, n)) >>> take(4, iterate(lambda x: x + [len(x) + 1], [1])) [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]
To create an end list, a type signature (starting again in Haskell for clarity only) can be infiniteFinitely :: (a -> Maybe a) -> a -> [a] .
If we used list instead of Maybe in Python:
from itertools import takewhile def iterateFinitely(f, x): return map(lambda a: a[0], takewhile(len, iterate(lambda y: f(y[0]), [x])))
Usage example:
>>> list(iterateFinitely(lambda x: [x / 2] if x else [], 20)) [20, 10, 5, 2, 1, 0]
Since ending with a fake value is probably pretty common, you can also add a version of this function that does this.
def iterateUntilFalsy(f, x): return iterateFinitely(lambda y: [f(y)] if y else [], x)
Usage example:
>>> list(iterateUntilFalsy(lambda x: x / 2, 20)) [20, 10, 5, 2, 1, 0] >>> list(iterateUntilFalsy(lambda x: x[1:], [1,2,3,4])) [[1, 2, 3, 4], [2, 3, 4], [3, 4], [4], []]