Python 生成器 匿名生成器

参考资料:

  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….

普通生成器的写法:

1 def release(root_l):
2     if isinstance(root_l,list):
3         for sub in root_l:
4             for i in release(sub):
5                 yield i
6     else :
7         yield root_l    

解释:

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

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

匿名生成器的写法:

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

解释:

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

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

  一种写法:

1  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,所以也可以写出这样的形式。

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

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

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

1  g=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)

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

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

1 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

1 g=lambda x:(z for y in x for z in (isinstance(y,list) and g(y) or [y]))
1 a=[1,2,3,[4,5,6,[7,8,[9]]]]
2 
3 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])
原文地址:https://www.cnblogs.com/baobaopangzi88/p/5326732.html