Python生成器学习笔记
- 更多分享:http://www.catbro.cn
一、前言
- 生成器与迭代器可以说是python中比较强大的两个特性。
- 相对于迭代器,生成器则要强大、高级一些。
- 生成器用好了,你的代码将会变得非常的优雅。
- OK,在学习生成器之前,我们先通过demo来看生成器是如何创建的以及如何使用它
二、生成器的创建及使用
-
其实,创建生成器就像创建函数一样简单。
-
demo如下:
-
首先我们声明一个列表,我们要做的是把列表内的元素按从左到右依次输出
nested = [[1,2],[3,4,5],[6]]
-
我们通过创建一个函数来完成
def flatten(nested): for sublist in nested: for element in sublist: yield element;
-
调用如下:
nested = [[1,2],[3,4,5],[6]] for num in flatten(nested=nested): print(num);
-
输出如下:
1 2 3 4 5 6
-
如果你想通过一个类似上面的列表来创建一个单列表,我们也可以这样子做
lst1 = list(flatten(nested))
-
我们来打印下lst1的元素
print(lst1) : [1, 2, 3, 4, 5, 6]
-
代码是死的,人是活的,对于一个需求,我们有不同的方法去处理,当然,加入我们刚接触编程,经验不多,用的方法可能就比较笨,但技术是个积累的过程,1w小时理论同样适用。
-
ok,我们前面创建的生成器比较死板,我们是根据列表才编写的,里面只处理来两层嵌套,假如我的数据是多层嵌套的,那就不适用了。
-
这时你可能会说,那你再改改不就可以了么?
-
咱是要写优雅的代码的人,怎么能这么敷衍了事呢。
-
Ok,我们再对上面的函数改改把!
def flatten(nested): try: for sublist in nested: for element in flatten(sublist): yield element; except TypeError: yield nested;
-
调用如下:
nested = [[1,2],[3,4,[5,[6,7]]],[8]] for num in flatten(nested=nested): print(num);
-
输出:
1 2 3 4 5 6 7 8
-
修改解说: 1、首先我们方法借助了递归。 2、其会一直调用递归,当调用flatten函数时传入的不是列表了,就会报TypeError错误,然后yield 该元素,yield你可以暂时看成return来理解。然后for in 里的element就是返回的元素,进而递归结束,这样子理解还是晕晕的其实,后面我们会单独一篇文章来讲解yield。
-
Ok,其实上面的函数有个bug,如果列表的元素是一个字符串,那么会发生什么问题呢?没错,当时会报错,因为我们的字符串是不能使用for in的。我们再稍微修改一下下。
-
flatten加强版!
def flatten(nested): try: try:nested+'' except TypeError: pass; else: raise TypeError('element can not be string'); for sublist in nested: for element in flatten(sublist): yield element; except TypeError as e: yield nested;
-
在遍历前对其进行一个+操作,如果其nested+‘‘没有报错,说明其是字符串,然后我们执行raise 触发一个TypeError异常,让其直接调用下面的yield nested返回,不再进行for in 及递归调用。
-
现在你可以愉快的在列表中加入字符串元素来。
-
调用如下:
nested = [['hello',2],[3,4,[5,[6,7]]],[8]] for num in flatten(nested=nested): print(num);
-
输出如下:
hello 2 3 4 5 6 7 8
-
小结:生成器就是一个包含yield关键字的函数。当函数被调用时,在函数体中的代码不会被马上执行,而会返回一个迭代器。每次请求一个值,就会执行生成器中的代码,直到遇到一个yield或者return语句。
-
yield语句表示应该生成一个值。
-
return语句表示生成器要停止执行。return语句只有在一个生成器中使用时才能进行无参数调用。
-
生成器是由两部分组成
1、生成器函数:用def 语句定义的包含yield部分 2、生成器迭代器 : 函数的返回部分
- 本次我们就先简单的学习生成器的创建和使用。
- 小伙伴们有什么好的建议都可以给我留言哦!