Python学习笔记--迭代器&生成器
2016-05-08 00:00
661 查看
一、Python迭代器
What?(Python迭代器是什么?)在使用Python进行编程时,经常会使用for语句对一个对象进行遍历,获取所需数据,如
li = [1, 2, 3, 4, 5] for i in li: print i像list、dict、string这一类可以使用for语句直接进行遍历的对象,称之为可迭代对象(Iterable),所谓可迭代对象,即为一类实现了__iter__()方法的对象,这类对象通过__iter__()方法返回一个迭代器,从而实现迭代操作;而所谓的迭代器对象(Iterator),即为一类实现了next()方法的对象,这类对象通过next()方法在一定范围内返回用户所期望的数据,超出范围则抛出StopIteration异常,并终止迭代
How?(如何创建并使用迭代器对象?)
下面这段代码自定义了一个迭代器对象MyIter,通过遍历该对象,可以获得[0, n)范围内的所有自然数
可以看到,MyIter既实现了__iter__()方法,又实现了next()方法,所以MyIter对象既是可迭代对象,又是迭代器对象
那么这中兼具双重身份的对象与单纯的可迭代对象又有什么区别呢?
下面先看如下这个例子,这个例子将MyIter对象与list对象进行了一次比较
上图中,方框1&2和方框3&4分别为对MyIter和list对象返回的迭代器进行两次迭代操作的结果,由结果可知,MyIter的迭代器只能进行一次迭代操作,而list的迭代器可以进行多次迭代操作。
原因:这主要是因为兼具双重身份的迭代器对象,每次通过iter()方法返回的都是该对象自身,然后通过该对象自身的next()方法实现遍历操作,所以当执行完一次遍历操作后,该对象的next()函数就到了越界的位置,下次再对该对象进行遍历时,就已经处于越界位置,所以返回结果应该为一个StopIteration异常。而单纯的可迭代对象,每次调用iter()函数时都会返回一个指定的迭代器对象的新实例,所以执行几次iter()方法就会产生几个不同的迭代器实例,每次迭代时,都是调用不同的迭代器实例的next()方法返回相应的数据,所以该类可迭代对象就能实现多次遍历操作。
验证:自己实现一个单纯的可迭代对象
可以看到,在上面例子中,两次对MyPureIter对象进行迭代,会得到两次迭代结果,这和上面的list的效果是相同的,从而验证了我们的说法。所以当我们需要多次对同一个可迭代对象进行迭代操作时,需要采用这种方式。
二、Python生成器
What?Python生成器是一个能有快速创建迭代器的强有力的工具。生成器看上去和普通函数类似,但是当需要返回数据时,使用yield关键字进行声明,而非return关键字。每次调用生成器的next()函数时,生成器会返回yield关键字后面的内容,并记住这次的返回位置和函数内部变量状态,用于下一次调用时进行恢复。
How?
创建生成器
下面的示例演示了通过yield关键字生成一个迭代器的过程
生成器的特点
生成器会自动生成迭代器的__iter__()方法和next()方法
在两次调用间函数的执行状态和局部变量会自动保存
生成器的执行流程
第一次调用:i=0, yield i,返回0,保存变量i的值0及这次函数执行的位置
第二次调用:恢复函数状态i=0,i += 1, 从而i=1,返回1,保存变量i的值1及这次函数执行的位置
。。。
第五次调用:恢复函数状态i=3,i += 1, 从而i=4,返回1,保存变量i的值1及这次函数执行的位置
第六次调用:恢复函数状态i=4,i += 1, 从而i=5,i>=n,函数结束
Why?
使用生成器能够比较方便快速地获得一个迭代器
使用生成器时采用的是惰性生成法则,只有需要时才生成相应的值,这样是内存友好的
三、Python生成器表达式
生成器表达式有点类似于列表表达式列表表达式:[expr for i in iterable if cond_expr](下面左图)
生成器表达式:(expr for i in iterable if cond_expr)(下面右图)
列表表达式与生成器表达式:
两者的写法不同,前者是中括号,后者是小括号
两者返回的值不同,前者返回一个列表,后者返回一个生成器
两者的作用不同,前者可以进行重复操作,多次迭代;后者只能进行一次迭代
后者比前者更加内存友好,所以当每次只需要返回一个值,并且不需要进行重复操作时,应该使用生成器表达式;而当一次需要使用列表中多个值,或者需要对列表元素进行多次操作时,则需要使用列表表达式
四、总结
Python迭代器是一类实现了__iter__()方法和next()方法的对象对于一个可迭代对象,for语句可以通过iter()方法获得该对象的迭代器对象,然后通过迭代器对象的next(0方法依次获得想要的元素
当可迭代对象同时也是迭代器对象时,无法进行独立的迭代操作;而像list这类可迭代对象,其迭代器对象是独立存在的,这时就可以重复进行迭代操作
生成器是一类特殊的函数,这类函数不通过return语句返回值,而是通过yield关键字返回一次返回一个结果,通过使用生成器,可以比较方便快捷地获得迭代器对象
生成器表达式与列表表达式非常相似,不过两者的具体使用场景和作用不同,需要根据具体使用场景选择相信的表达式
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- 设计模式之行为型模式 - 调用行为的传递问题
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例