我听说在Python中不能添加多行lambdas,因为它们会在语法上与Python中的其他语法结构冲突。今天在公交车上,我一直在思考这个问题,并意识到我想不出任何一个Python构造可以与多行lambdas相冲突。考虑到我对这门语言相当熟悉,这让我很惊讶。
现在,我相信Guido没有在语言中包含多行lambda是有原因的,但出于好奇:在什么情况下,包含多行lambda会有歧义?我听说的是真的吗,还是有其他原因导致Python不允许多行lambda ?
我听说在Python中不能添加多行lambdas,因为它们会在语法上与Python中的其他语法结构冲突。今天在公交车上,我一直在思考这个问题,并意识到我想不出任何一个Python构造可以与多行lambdas相冲突。考虑到我对这门语言相当熟悉,这让我很惊讶。
现在,我相信Guido没有在语言中包含多行lambda是有原因的,但出于好奇:在什么情况下,包含多行lambda会有歧义?我听说的是真的吗,还是有其他原因导致Python不允许多行lambda ?
当前回答
我只是玩了一点,试图用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
其他回答
(对于仍然对这个话题感兴趣的人。)
考虑一下这一点(甚至包括在“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
我很内疚在我的一些更简单的项目中实践了这个肮脏的hack:
lambda args...:( expr1, expr2, expr3, ...,
exprN, returnExpr)[-1]
我希望你能找到一种方法保持python化,但如果你必须这样做,这比使用exec和操纵全局变量要少一些痛苦。
看看下面这些:
map(multilambda x:
y=x+1
return y
, [1,2,3])
这是一个lambda返回(y,[1,2,3])(因此映射只得到一个参数,导致错误)?还是返回y?或者这是语法错误,因为新行上的逗号放错了地方?巨蟒怎么知道你想要什么?
在paren中,缩进对python来说并不重要,因此不能明确地使用多行。
这只是一个简单的例子,可能还有更多的例子。
Guido van Rossum (Python的发明者)在一篇旧博客文章中亲自回答了这个问题。 基本上,他承认这在理论上是可能的,但任何提出的解决方案都是非python的:
“但对我来说,这个谜题的任何解决方案的复杂性都是巨大的:它要求解析器(或者更准确地说,词法分析器)能够在缩进敏感和不缩进模式之间来回切换,保持先前模式的堆栈和缩进水平。从技术上讲,这些问题都可以解决(已经有一堆缩进级别可以被一般化)。但这些都不能改变我的直觉,那就是这一切都是一个精心设计的鲁布·戈德堡(Rube Goldberg)的精巧装置。”
以下是几个相关的连结:
有一段时间,我一直在跟踪Reia的开发,它最初也将在Erlang之上使用Python的基于缩进的语法和Ruby块。但是,设计师最终放弃了缩进敏感性,他写的这篇文章包括了他在缩进+多行块中遇到的问题的讨论,以及他对Guido的设计问题/决策的更多欣赏:
http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html
另外,这里有一个关于ruby风格的Python块的有趣建议,我遇到过Guido发布了一个响应,实际上没有将它击落(虽然不确定是否有任何后续的击落):
http://tav.espians.com/ruby-style-blocks-in-python.html