1、迭代器
(1)可迭代对象:
什么是可迭代对象:
我们常见的数据量类型有list,str,tuple,set,dict以及文件句柄都是可迭代对象,因为他们中都包含了__iter__方法。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 l = [1,2,3] 2 s = 'alex' 3 t = (1,2,3) 4 set = {1,2,3,4} 5 dict = {'name':'twonss','age':20} 6 7 f = open('log',encoding='utf-8',mode='w') 8 print('__iter__' in dir(l)) 9 print('__iter__' in dir(s)) 10 print('__iter__' in dir(t)) 11 print('__iter__' in dir(set)) 12 print('__iter__' in dir(dict)) 13 print('__iter__' in dir(f))
结果:
PS:dir()是python内置的函数,可以打印出每个数据类型的所有可用方法
(2)迭代器:
什么是迭代器:
我们常见的数据类型也都只是可迭代对象而已,但是文件句柄却是一个迭代器,迭代器内部不仅包含了__iter__方法,还包含了__next__方法,并且可以被for循环遍历,好处就是可以节省内存空间。
以文件句柄举例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 f = open('log',encoding='utf-8',mode='w') 2 print('__iter__' in dir(f)) 3 print('__next__' in dir(f))
结果:
(3)将我们常见的数据类型变成迭代器:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 l = [1,2,3] 2 s = 'alex' 3 t = (1,2,3) 4 set = {1,2,3,4} 5 dict = {'name':'twonss','age':20} 6 7 l1 = l.__iter__() 8 s1 = s.__iter__() 9 t1 = t.__iter__() 10 set1 = set.__iter__() 11 dict1 = dict.__iter__() 12 13 print('__next__' in dir(l1)) 14 print('__next__' in dir(s1)) 15 print('__next__' in dir(t1)) 16 print('__next__' in dir(set1)) 17 print('__next__' in dir(dict1))
结果:
(4)迭代器的取值方式:
迭代器的取值方式用的就是__next__方法,每next一次只取一个值,想取完所有值就要一直next,直到取完报StopIteration错误为止。
示例1:
l1 = l.__iter__() print(l1.__next__()) print(l1.__next__()) print(l1.__next__()) print(l1.__next__())
结果:
示例2:
l1 = l.__iter__() while True: try: print(next(l1)) ##next() == __next__() except StopIteration: break
结果:
示例3:
l1 = l.__iter__() for i in l1: print(i)
结果:
(5)判断是否是可迭代对象和迭代器的两种方法:
a、判断是否是可迭代对象的第一种方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 l = [1,2,3] 2 s = 'alex' 3 t = (1,2,3) 4 set = {1,2,3,4} 5 dict = {'name':'twonss','age':20} 6 7 f = open('log',encoding='utf-8',mode='w') 8 print('__iter__' in dir(l)) 9 print('__iter__' in dir(s)) 10 print('__iter__' in dir(t)) 11 print('__iter__' in dir(set)) 12 print('__iter__' in dir(dict)) 13 print('__iter__' in dir(f))
第二种方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from collections import Iterable #用解释器自带的模块 2 3 print(isinstance(l,Iterable)) 4 print(isinstance(s,Iterable)) 5 print(isinstance(t,Iterable)) 6 print(isinstance(set,Iterable)) 7 print(isinstance(dict,Iterable)) 8 print(isinstance(f,Iterable))
b、判断是否是迭代的第一种方法:
print('__next__' in dir(f))
第二种方法:
from collections import Iterator print(isinstance(f,Iterator))
2、生成器:
生成器其实就是迭代器,可以被for循环遍历的一种函数,由于是是函数,所以会有返回值,但是在生成器里面不会用return返回结果,而是使用yield关键字去返回结果,yield每次都能返回一个或多个值,每遇到一个yield关键字时,函数就会挂起,下次执行时就会从它当前位置继续往下执行。
生成器格式:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def func1(): 2 print('one') 3 yield 1 4 print('two') 5 yield 2 6 print('three') 7 yield 3 8 print('four') 9 yield 4 10 11 g = func1() #这里执行函数的话不会去执行函数内部的代码,而是返回一个生成器对象 12 print(g) #<generator object func1 at 0x0000000001DF3E60> 13 14 如果想取到函数的执行结果的话必须像迭代器一样使用next()方法: 15 print(next(g)) 16 print(next(g)) 17 print(next(g))
结果:
PS:当然生成器的取值方式是和迭代器一样的,不止是next一次次的去取,也可以使用while循环和for循环去取。
send取值:
send取值和next取值的方式是一样的,不同的是,send在取下一个值时可以给上一个yield赋值,但是,send不能用于取第一个值,而且也不能给最后一个yield赋值。
示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def func1(): print('one') num = yield 1 print(num) print('two') yield 2 print('three') yield 3 g = func1() print(next(g)) print(g.send(123)) #123传给了num print(next(g))
结果:
取值第一个值是用send取,结果报错:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def func1(): 2 print('one') 3 num = yield 1 4 print(num) 5 print('two') 6 yield 2 7 print('three') 8 yield 3 9 10 g = func1() 11 print(g.send(123)) 12 print(g.send(456)) 13 print(next(g))
结果:
3、列表表达式和生成器表达式:
列表表达式:
例如生成一个列表,列表的内容为[python1期,python2期,python3期,...]
常规的生成方式是:
l1 = [] for i in range(1,11): l1.append('python%s期'%i) print(l1)
使用列表表达式的生成方式是:
['python%s期' %i for i in range(1,11)]
结果:
列表表达式里还可以使用if判断:
比如判断打印大于5的每一期:
['python%s期' %i for i in range(1,11) if i > 5 ]
结果:
PS:在列表表达式里面,不仅可以做判断,还可以循环里面套循环
生成器表达式:
生成器表达式就是把列表表达式的[]换成了(),然后用next去取值,当然也 可以使用for循环:
ret = ( 'python%s期' %i for i in range(1,11)) print(next(ret)) print(next(ret)) print(next(ret)) print(next(ret)) print(next(ret))
结果: