Модификация функционального python compose () для возврата списка всех промежуточных значений - PullRequest
0 голосов
/ 22 июня 2019

В Python 3 вот моя однострочная функция составления, которую я пытаюсь изменить:

def compose(*fncs):
  return functools.reduce(lambda f,g: lambda x: f(g(x)), fncs, lambda x: x)

Когда я сочиняю функцию с c = compose(h, g, f), вызов c(x) эквивалентен вызову h(g(f(x))

Изменяя существующую однострочную оболочку как можно меньше, я хотел бы создать функцию compose_intermed(*fncs), которая возвращает немного другой вид составной функции. При вызове этой функции возвращается не конечное значение составных функций, а список, первый элемент которого является окончательным значением, за которым следуют все промежуточные значения на каждом шаге, на котором применяются составные функции.

Когда я сочиняю функцию с ci = compose_intermed(h, g, f), вызов ci(x) вернет список [h(g(f(x))), g(f(x)), f(x)].

Я бы хотел как можно меньше изменить функцию компоновки , продолжая использовать reduce или, возможно, понимание списка, а не циклы. Я знаю, что может быть более простых способов сделать это, но я пытаюсь использовать это как упражнение для улучшения моего общего понимания взаимосвязи функционального программирования и Python 3.

Дополнительный вопрос: Есть ли у этой функции еще одно более стандартизированное имя в мире функционального программирования? Я искал несколько библиотек и еще не нашел библиотечной функции для того, что я пытаюсь сделать.

1 Ответ

1 голос
/ 22 июня 2019

Комментарий Рай - хорошая отправная точка. В этом посте я постараюсь продемонстрировать, о чем он / она говорит -

from functools import reduce

def identity(x):
  return x

def pipeline(f = identity, *fs):
  return reduce(lambda r,f: lambda x: f(r(x)), fs, f)

Сделайте две простые функции и протестируйте их. Обратите внимание, как pipeline применяет функции слева направо -

def add1(x):
  return x + 1

def mult2(x):
  return x * 2

f = pipeline(mult2, add1, add1, add1)

print(f(10))
# 23

Затем внедрите pipeline_intermediate. Так же, как Ry комментарии, вывод в конце инвертируется с помощью [::-1] -

def pipeline_intermediate(f = identity, *fs):
  return lambda x: reduce(lambda r,f: [f(r[0])]+r, fs, [f(x)]) [::-1]

g = pipeline_intermediate(mult2, add1, add1, add1)

print(g(10))

# [20, 21, 22, 23]

Теперь вы можете увидеть, как реализовать справа налево compose_intermediate? Вы понимаете, почему это сложнее?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...