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

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


当前回答

关于丑陋的黑客,你总是可以使用exec和常规函数的组合来定义一个多行函数,就像这样:

f = exec('''
def mlambda(x, y):
    d = y - x
    return d * d
''', globals()) or mlambda

你可以把它包装成这样一个函数:

def mlambda(signature, *lines):
    exec_vars = {}
    exec('def mlambda' + signature + ':\n' + '\n'.join('\t' + line for line in lines), exec_vars)
    return exec_vars['mlambda']

f = mlambda('(x, y)',
            'd = y - x',
            'return d * d')

其他回答

让我试着解决@balpha解析问题。我会用圆括号括住多行。如果没有括号,lambda定义是贪婪的。所以in

map(lambda x:
      y = x+1
      z = x-1
      y*z,
    [1,2,3]))

返回一个函数,返回(y*z, [1,2,3])

But

map((lambda x:
      y = x+1
      z = x-1
      y*z)
    ,[1,2,3]))

意味着

map(func, [1,2,3])

func是返回y*z的多行lambda。这有用吗?

在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]

在lambda项之间传递任意数量变量的一个安全方法:

print((lambda: [
    locals().__setitem__("a", 1),
    locals().__setitem__("b", 2),
    locals().__setitem__("c", 3),
    locals().get("a") + locals().get("b") + locals().get("c")
])()[-1])

输出:6

我只是玩了一点,试图用reduce来理解字典,并想出了这个一行hack:

In [1]: from functools import reduce
In [2]: reduce(lambda d, i: (i[0] < 7 and d.__setitem__(*i[::-1]), d)[-1], [{}, *{1:2, 3:4, 5:6, 7:8}.items()])                                                                                                                                                                 
Out[3]: {2: 1, 4: 3, 6: 5}

我只是试图做同样的事情,在这个Javascript字典理解:https://stackoverflow.com/a/11068265

我从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表达式本身做多行,但如果有人得到这个线程,看看如何调试表达式(像我),我认为这将有所帮助