代码之家  ›  专栏  ›  技术社区  ›  snoob dogg

为什么这个lambda函数在else语句中的行为很奇怪?

  •  6
  • snoob dogg  · 技术社区  · 8 年前

    有人能告诉我为什么 <function <lambda>.<locals>.<lambda> at 0x0000000002127F28> 而不是 3 ?

    >>> foo = True
    >>> bar = lambda x: x + 1 if foo else lambda x: x + 2
    >>> bar(1)
    2
    
    >>> foo = False
    >>> bar = lambda x: x + 1 if foo else lambda x: x + 2
    >>> bar(1)
    <function <lambda>.<locals>.<lambda> at 0x0000000002127F28>   # Hey !? WTF ? 
    
    3 回复  |  直到 8 年前
        1
  •  6
  •   Rory Daulton    8 年前

    python的操作顺序与您在这里想象的不同。看来你应该把你的定义改为

    bar = (lambda x: x + 1) if foo else (lambda x: x + 2)
    

    你的定义实际上是

    bar = lambda x: (x + 1 if foo else lambda x: x + 2)
    

    换句话说,您正在返回一个函数,如果 foo 为true,函数返回 x+1 但如果它为false,则返回函数 lambda x: x + 2 . 您真正想要的是返回两个函数中的一个,修改后的定义就是这样做的。

    这个故事的寓意是:用大量的括号来说明你的意图。


    对你的问题的评论暗示了另一种可能性:

    bar = lambda x: x + 1 if foo else x + 2
    

    相当于

    bar = lambda x: (x + 1 if foo else x + 2)
    

    这和我的建议不一样。执行时,我的建议返回两个函数之一。一个函数总是添加一个,另一个总是添加2,返回的函数取决于 执行定义行时 . 这里的替代方法只返回一个函数,并且此函数根据 当函数被计算时 . 你看到区别了吗?替代方案的变化更频繁。只有你能说出哪一个符合你的需要。

        2
  •  0
  •   Scott Hunter    8 年前

    您的if is_t在lambdas之间选择,它选择第一个lambda返回的是什么;在本例中,是另一个lambda。试着加上括号来说明你的意思。

        3
  •  0
  •   swiftg    8 年前

    正如其他人指出的,如果这样写的话,效果会更好:

    bar = (lambda x: x + 1) if foo else (lambda x: x + 2)
    

    但是在定义了条之后,更改foo没有任何效果,除非您以相同的方式重新定义条。如果您想通过更改foo获得不同的结果,请尝试以下操作:

    bar = lambda x: (x + 1 if foo else x + 2)