Создайте new_function, которая имеет input n и input_function, которые возвращают output_function, которая делает то, что input_function делает n раз - PullRequest
0 голосов
/ 17 мая 2018

Я хотел бы создать новую функцию, которая имеет два входа (n, input_function), которая возвращает новую функцию output_function, которая выполняет функцию input_function, но она делает это n раз. Вот изображение того, чего я пытаюсь достичь

def repeat_function(n, function, input_number):
    for i in range(n):
        input_number = function(input_number)
    return input_number

def times_three(x):
    return x * 3

print(repeat_function(3, times_three, 10))  #prints 270 so it's correct
print(times_three(times_three(times_three(10))))  #prints 270 so it's correct

#This function does not work
def new_repeat_function(n, function):
    result = lambda x : function(x)
    for i in range(n-1):
        result = lambda x : function(result(x))
    return result

new_function = new_repeat_function(3, times_three)
#I want new_function = lambda x : times_three(times_three(times_three(x))) 
print(new_function(10)) # should return 270 but does not work

Я старался изо всех сил, чтобы реализовать это, но это не работает. Мне нужна функция new_repeat_function, чтобы делать то, что делает repeat_function, но вместо возврата и целочисленного ответа, как это делает repeat_function, функция new_repeat_function должна возвращать time_three () n раз.

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

Вам необходимо вернуть функцию, а не результат.

def new_repeat_function(n, function):
    def repeat_fn(x):
        result = function(x)
        for i in range(n - 1):
            result = function(result)
        return result

    return repeat_fn

Здесь вы создаете замыкание, которое захватывает параметры n и function.Позже, когда вы вызываете возвращенное замыкание, оно использует n и function, поскольку они были переданы в new_repeat_function.Итак, если мы позвоним

new_func = new_repeat_function(3, three_times)
print(new_func(10))

, мы получим 270, как и ожидалось.

0 голосов
/ 17 мая 2018

Вы можете просто вернуться на repeat сам. Т.е. вам не нужно создавать range или использовать цикл вообще

def repeat (n, f):
  return lambda x: \
    x if n is 0 else repeat (n - 1, f) (f (x))

def times_three (x):
    return x * 3

new_func = repeat (3, times_three)

print (new_func (10))
# 270

Вы также можете пропустить промежуточные задания

print (repeat (0, times_three) (10))
# 10

print (repeat (1, times_three) (10))
# 30

print (repeat (2, times_three) (10))
# 90
0 голосов
/ 17 мая 2018

Что вам нужно сделать, это создать function, который создает еще один function, в python этот шаблон называется decorators, здесь у вас есть пример:

from functools import wraps

def repeated(n):
  def wrapped(f):
    @wraps(f)
    def ret_f(*args, **kwargs):
      res = f(*args, **kwargs)
      for _ in range(1, n):
        res = f(res)
      return res
    return ret_f
  return wrapped

@repeated(2)
def times_three(x):
    return x * 3

print(times_three(10))

Вы можете попробовать жить здесь

...