简体   繁体   中英

All purpose recursive function

There are two recursive functions fn(f, n) , the first one evaluates this expression sin(sin(sin(sin(sin(1))))) = 0.587181

from math import sin


def fn(f, n):
    def fn_inside(x):
        for i in range(n):
            x = f(x)
        return x
    return fn_inside


f1 = fn(lambda x: "sin(%s)" % x, 5)
f2 = fn(lambda x: sin(x), 5)
print("%s = %f" % (f1("1"), f2(1)))

The next one calculates the ratio (1/1, 2/1... 13/8...) of adjacent numbers from the Fibonacci series (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 - each number is the sum of the two preceding ones, starting from 0 and 1) at the distance (precision) from the beginning as the golden ratio

distance = 4

def fn(f, n):
    def fn_inside(*x):  # there is the difference
        for i in range(n):
            x = f(*x)   # there is the difference
        return x
    return fn_inside


def next_fib(i, j):
    return j, j + i


def golden_ratio(n):
    get_fib_n = fn(next_fib, n+1)
    i, j = get_fib_n(0, 1)
    return j / i


print(golden_ratio(distance))

As you can see here the difference in the accepted argument f(*x). And I got stuck hard to write a universal function that will work in both the first and second cases. golden_ratio(n) can be changed too. Because if we remove the * then for the second case we get an error

TypeError: fn_inside() takes 1 positional argument but 2 were given

otherwise the error is different

x = f(*x)
TypeError: <lambda>() takes 1 positional argument but 6 were given

First, notice that there is no recursion here. fn is a higher-order function — it operates on functions — but it is not recursive, ie, it does not call itself.

In your first snippet, the function f takes a single argument and returns a single value. In the second snippet, it takes two arguments and returns a tuple. This is why you need to structure the code differently.

The obvious way to work around this would be to make next_fib take a single argument, which is a tuple, instead of two arguments.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM