python lambda求值表达式



我正在尝试在python中使用lambda,并遇到了这个问题:

def foo(y):
return lambda x: x(x(y))
def bar(x):
return lambda y: x(y)
print((bar)(bar)(foo)(2)(lambda x:x+1))

谁能解释/分解这段代码是如何工作的?我在试图弄清楚x和y是什么时遇到了问题。

Lambda函数只是函数。它们几乎是合成糖,你可以想到这个结构:

anony_mouse = lambda x: x # don't actually assign lambdas

等价于这个结构:

def anony_mouse(x):
return x

(几乎,因为没有其他方法可以获得一个函数而不将赋值给某个变量,并且语法阻止您使用它们做一些事情,例如使用多行。)

因此,让我们用标准函数符号写出上面的例子:

def foo(y):
# note that y exists here
def baz(x):
return x(x(y))
return baz

我们有一个工厂函数,它生成一个函数…期望使用函数(x)调用,并返回x(x(arg_to_factory_function))。考虑:

>>> def add_six(x):
return x + 6
>>> bazzer = foo(3)
>>> bazzer(add_six) # add_six(add_six(3)) = 6+(6+3)

我还可以继续,但这样就更清楚了吗?

顺便说一下,这些代码很可怕,几乎让我同意Guido的观点,即lambda很糟糕。

第一个' (bar) '等于' bar ',所以它是一个普通的函数调用,第二个参数调用,即bar(bar) -将' x '替换为' bar ',你会得到什么是bar(bar)的结果;' (foo) '参数传递给bar(bar)的结果它将是一个带有一些参数的lambda函数。-将其替换为' foo '并获得结果,以此类推,直到到达表达式

的末尾

我稍微修改了一下原始函数,以便更清楚地了解发生了什么(因此应该更清楚哪个参数是可调用的!)

# given a function it evaluates it at value p
def eval(func):      # your foo
return lambda p: func(p)
# given a value p perform a double composition of the function at this value (2-step recursion)
def iter_2(p):      # your bar
return lambda func: func(func(p))
increment = lambda x: x + 1  # variable binding only for readability

这个例子很难理解,因为其中一个函数eval没有做什么特别的事情,它的组合等于恒等!…这可能会让人很困惑。

  • (foo)(2)(lambda x:x+1)):
x = 2
iter_2(x)(increment) # increment by 2 because iter_2 calls increment  twice
# 4
  • 幂等性:(或与自身组合返回恒等函数)
increment(3) == eval(increment)(3)
# True
# idempotency - second composition is equivalent to the identity
eval(increment)(3) == eval(eval)(increment)(3)
# True
eval(increment)(3) == eval(eval)(eval)(increment)(3)
# True
# ... and so on
  • final:幂等的结果->bar什么都不做,只是混乱
eval(eval)(iter_2)(x)(increment) == iter_2(x)(increment)
# True
评论>:在(bar)(bar)(foo)(2)(lambda x:x+1)中,可以省略第一项周围的括号,只使用bar(bar)(foo)(2)(lambda x:x+1)

题外话:[因为你的例子很吓人]

Lambda函数也被称为匿名函数。为什么呢?仅仅是因为它们不需要声明。它们被设计为单一用途,所以你应该"永远不要"。赋值给一个变量。例如,在函数式编程的背景下,其基本成分是……函数!它们用于修改其他函数的行为(例如通过装饰!)。你的例子只是一个独立的语法…本质上是一个无意义的例子,它隐藏了真相"力量"。函数的。在此基础上还有一个数学分支叫做λ演算。

这里有一个完全不同的lambda函数应用示例,用于装饰(但这是另一个故事):

def action(func1):
return lambda func2: lambda p: func2(p, func1())
def save(path, content):
print(f'content saved to "{path}"')
def content():
return 'content' # i.e. from a file, url, ...
# call
action(content)(save)('./path')
# with each key-parameter would be
action(func1=content)(func2=save)(p='./path')

输出
content saved to "./path"