Python 2.7 Grammar Geek - Lambda in List Comprehensions



你能构建一个与以下Python 2.7语法规则匹配的最小有效源代码示例吗?是否可以在不产生运行时错误的情况下?

(1) atom:           '[' [listmaker] ']'
(2) listmaker:      test  list_for
(3) list_for:       'for' exprlist 'in' testlist_safe
(4) testlist_safe:  old_test
(5) old_test:       old_lambdef
(6) old_lambdef:    'lambda' [varargslist] ':' old_test

到目前为止,我能达到的最好的结果是:

L = [ fn() for fn in (lambda: x for x in xrange(3)) ]

但是我的解决方案的问题是"lambda"周围的括号。你能建立一个没有括号的例子吗?如果不是,那么你将如何解释为什么你不能在lambda中构建,即使它完全符合语法规则?

[x for x in lambda: 1]

这很简单。当然,这将在运行时生成 TypeError,但语法并非旨在排除将产生 TypeError 的构造。

运行时没有异常就无法做到这一点,因为old_lambdef总是计算为函数对象,而函数对象不可迭代。在old_lambdef的结构中,没有任何地方可以插入一些东西来使 Python 调用该函数;Python 将尝试遍历函数对象本身,而不是调用它并迭代返回值。


testlist_safeold_test定义的完整形式是

testlist_safe: old_test [(',' old_test)+ [',']]
old_test: or_test | old_lambdef

testlist_safe并不总是一个单一的old_testold_test也不总是一个old_lambdef。允许testlist_safe成为old_test,允许old_test成为old_lambdef。一起做这些事情总是会在运行时产生异常,但它们不会仅仅为了阻止人们一起做这些事情而使语法复杂化。

最新更新