Cam.Davidson.Pilon
Cam.Davidson.Pilon

Reputation: 1726

apply a function to a variable over and over again

Is there a better way to apply a function to a variable over and over again, without having to use a for loop (ideally in standard lib too)? Example of what I have now:

def simulation():
    wealth = 0
    for i in range(1000):
       wealth = gamble(wealth)
    return wealth

What I would love is something like

def simulation()
    return reduce_(gamble, 1000, 0)

Upvotes: 0

Views: 105

Answers (3)

Blckknght
Blckknght

Reputation: 104772

Unfortunately, there's no builtin or standard library function that does quite what you want.

While you can contort an existing function to make it work, a for loop is probably more readable than the code that would require. I, for one, would greately prefer to read your current code than Austin Hasting's very clever version. I can understand the for loop immediately, the reduce call and the lambda that ignores its second argument both require quite a bit more thought.

So, think carefully before you "simplify" your code and make sure your simplification doesn't actually make the code harder to understand.

Upvotes: 1

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160607

One alternative I could think of is using itertools.repeat with map:

from itertools import repeat
wealth = 0

# dummy gable function
def gamble(wealth): 
    return wealth

z = map(gamble, repeat(wealth, times=1000))

You'd still need to iterate through it (or call list() on it) to get it to execute.

This is if the function should act on the same value. If you need it to call itself many times you could also use a decorator (or reduce but there's no point in adding this since @Austin did):

def apply(f, times=10):
    def func(*args, **kwargs):
        nonlocal times
        times -= 1
        if times:
            return func(f(*args, **kwargs))
    return func

@apply
def foo(val): 
    val += 1
    print(val, end = " ")
    return val

foo(10)
11 12 13 14 15 16 17 18 19

Upvotes: 2

aghast
aghast

Reputation: 15310

# python 3
from functools import reduce
return reduce(lambda w,i: gamble(w), range(1000), 0)

Upvotes: 1

Related Questions