取代python的 and or 的x if y else z方法,补充匿名递归方法

原创
2012/11/25 22:57
阅读数 7.2K

今天在弄我的语法分析器的时候,为了观察结果,我想找一个压平嵌套列表的函数(我写了个但是不太满意,记得cnblogs有看到过),于是搜了一下,找到了这篇文章:

http://www.cnblogs.com/c-hy/archive/2012/09/21/2696703.html

里面的lambda函数让我很满意,但是有个用法确实第一次见,函数如下:

flat=lambda L: sum(map(flat,L),[]) if isinstance(L,list) else [L,]
注意里面的一个用法, x if y else z

这个用法的效果是,如果y真,返回x,否则返回z。

而且这个用法是表达式,不是语句!

可以算是一个语法糖,从上面可以看到,通过赋值lambda实现了递归(一次可以实现变向的循环),通过这个语法糖又实现了选择,因此极大增强了lambda的威力。可惜就是不赋值的话,还是实现不了递归,希望能够有所改进,但是现在已经很接近lisp的表达能力了。

这个用法是表达式,并不局限与lambda语句内的。

因此我们可以这样写:

x=3*4/7
y='a'
z='b'
t=y if int(x) else z

最后提供两个lambda函数:

#解包函数,将递归的解包,直到参数是原子或者长度大于1的列表
wrap=lambda L: tuple(wrap(list(L))) if isinstance(L,tuple) else L if not isinstance(L,list) else map(wrap,L) if len(L)>1 else wrap(L[0])
#压平列表,对元组也会进行压平,但仍返回元组
flat=lambda L: sum(map(flat,L),[]) if isinstance(L,list) else [tuple(flat(list(L))),] if isinstance(L,tuple) else [L,]

ps:我才意识到,python的while、for、try也可以接else子句,受教育了

补充,lambda的匿名递归方法,lambda也可以实现递归的,方法是利用参数默认值来实现赋值的命名操作,从而保证函数的匿名性。

(lambda n,s=lambda n,f:1 if n<2 else f(n-1,f)*n:s(n,s))(10)
展开阅读全文
加载中

作者的其它热门文章

打赏
0
5 收藏
分享
打赏
0 评论
5 收藏
0
分享
返回顶部
顶部