我听说在Python中不能添加多行lambdas,因为它们会在语法上与Python中的其他语法结构冲突。今天在公交车上,我一直在思考这个问题,并意识到我想不出任何一个Python构造可以与多行lambdas相冲突。考虑到我对这门语言相当熟悉,这让我很惊讶。

现在,我相信Guido没有在语言中包含多行lambda是有原因的,但出于好奇:在什么情况下,包含多行lambda会有歧义?我听说的是真的吗,还是有其他原因导致Python不允许多行lambda ?


当前回答

我从python开始,但来自Javascript的最明显的方式是提取表达式作为函数....

人为的例子,乘法表达式(x*2)被提取为函数,因此我可以使用multiline:

def multiply(x):
  print('I am other line')
  return x*2

r = map(lambda x : multiply(x), [1, 2, 3, 4])
print(list(r))

https://repl.it/@datracka/python-lambda-function

也许它并没有确切地回答这个问题,如果这是如何在lambda表达式本身做多行,但如果有人得到这个线程,看看如何调试表达式(像我),我认为这将有所帮助

其他回答

看看下面这些:

map(multilambda x:
      y=x+1
      return y
   , [1,2,3])

这是一个lambda返回(y,[1,2,3])(因此映射只得到一个参数,导致错误)?还是返回y?或者这是语法错误,因为新行上的逗号放错了地方?巨蟒怎么知道你想要什么?

在paren中,缩进对python来说并不重要,因此不能明确地使用多行。

这只是一个简单的例子,可能还有更多的例子。

我知道这是一个老问题,但是为了记录,这里有一种多行lambda问题的解决方案,其中一个调用的结果被另一个调用消耗。

我希望它不是超级hack,因为它只是基于标准库函数,没有使用dunder方法。

下面是一个简单的例子,我们从x = 3开始,然后在第一行加1,然后在第二行加2,得到6作为输出。

from functools import reduce

reduce(lambda data, func: func(data), [
    lambda x: x + 1,
    lambda x: x + 2
], 3)

## Output: 6

Guido van Rossum (Python的发明者)在一篇旧博客文章中亲自回答了这个问题。 基本上,他承认这在理论上是可能的,但任何提出的解决方案都是非python的:

“但对我来说,这个谜题的任何解决方案的复杂性都是巨大的:它要求解析器(或者更准确地说,词法分析器)能够在缩进敏感和不缩进模式之间来回切换,保持先前模式的堆栈和缩进水平。从技术上讲,这些问题都可以解决(已经有一堆缩进级别可以被一般化)。但这些都不能改变我的直觉,那就是这一切都是一个精心设计的鲁布·戈德堡(Rube Goldberg)的精巧装置。”

在Python 3.8/3.9中有赋值表达式,因此可以在lambda中大量使用 扩展功能

例如,代码

#%%
x = 1
y = 2

q = list(map(lambda t: (
    tx := t*x,
    ty := t*y,
    tx+ty
)[-1], [1, 2, 3]))

print(q)

将打印[3,6,9]

(对于仍然对这个话题感兴趣的人。)

考虑一下这一点(甚至包括在“multiline”lambda中的进一步语句中使用语句的返回值,尽管它丑陋到令人作呕;-)

>>> def foo(arg):
...     result = arg * 2;
...     print "foo(" + str(arg) + ") called: " + str(result);
...     return result;
...
>>> f = lambda a, b, state=[]: [
...     state.append(foo(a)),
...     state.append(foo(b)),
...     state.append(foo(state[0] + state[1])),
...     state[-1]
... ][-1];
>>> f(1, 2);
foo(1) called: 2
foo(2) called: 4
foo(6) called: 12
12