您的位置:首页 > 编程语言 > Python开发

Python 生成器 匿名生成器

2016-03-27 20:39 507 查看
参考资料:

  Python yield使用浅析:http://www.liaoxuefeng.com/article/001373892916170b88313a39f294309970ad53fc6851243000

  问题源地址:https://www.zhihu.com/question/38868916

  这两天稍微了解了一下python的生成器和匿名生成器,总结一下。

现在有一个问题:

  让你展开一个嵌套若干列表的列表,例如[1,2,[3],[4,5,6,[7,8,[9]]]],然后要求是让你写一个生成器。返回的是1,2,3,4,5….

普通生成器的写法:

def release(root_l):
if isinstance(root_l,list):
for sub in root_l:
for i in release(sub):
yield i
else :
yield root_l


解释:

  这个生成器就是递归的去匹配list,然后返回值。其中要注意的是第二层的for循环,容易出错。release(sub)返回的是一个生成器,而不是值,所以需要再打开这个生成器。

  (不理解生成器的同学,可以去学习一下上面的链接,非常好的学习资料。)

匿名生成器的写法:

g=lambda x:(z for y in x for z in (isinstance(y,list) and g(y) or [y]))


解释:

  在解释这个生成器前,先了解一下lambda函数的递归。

  现在有个简单的问题:让你用匿名函数实现一个求阶乘的函数。

  一种写法:

fac=lambda n: 1 if n<=1 else n*fac(n-1)

#也可以写成这样

2 f= lambda n: n and n*f(n-1) or 1


  但是这种写法有一个问题,就是这个函数调用了全局变量fac,所以也可以写出这样的形式。

P=lambda self,n:n*self(self,n-1) if n>1 else 1


  这样写的好处是不涉及全局变量,更深入的,没查到什么资料。

有了这个基础知识,就可以解释一下上面的匿名生成器了:

1g=lambda x:(z for y in x for z in (isinstance(y,list) and g(y) or [y]))


解释:

  首先先看最外层的两个‘()’。在python lambda中,用[]推导出来的是迭代器(Iterables),用()推导出来的是生成器(Generators)。

  (参考:https://www.zhihu.com/question/24807364)

  其他的就和普通的生成器一样了。

另外,对于这个问题,如果不用生成器写的话,还看到一个很好玩的写法。

f=lambda x:sum([f(s) if isinstance(s,list) else [s] for s in x],[])


最后,推荐一篇,在查资料的过程中意外的看到关于函数式编程的文章
http://blog.csdn.net/pongba/article/details/1336028
update:16-03-29

g=lambda x:(z for y in x for z in (isinstance(y,list) and g(y) or [y]))


a=[1,2,3,[4,5,6,[7,8,[9]]]]

g=lambda s:(isinstance(s,list) and y or s for x in isinstance(s,list) and s or [1] for y in isinstance(s,list) and g(x) or [1])
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: