1、迭代器
(1)可迭代对象:
什么是可迭代对象:
我们常见的数据量类型有list,str,tuple,set,dict以及文件句柄都是可迭代对象,因为他们中都包含了__iter__方法。
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__' indir(l))9 print('__iter__' indir(s))10 print('__iter__' indir(t))11 print('__iter__' indir(set))12 print('__iter__' indir(dict))13 print('__iter__' in dir(f))
View Code
结果:
PS:dir()是python内置的函数,可以打印出每个数据类型的所有可用方法
(2)迭代器:
什么是迭代器:
我们常见的数据类型也都只是可迭代对象而已,但是文件句柄却是一个迭代器,迭代器内部不仅包含了__iter__方法,还包含了__next__方法,并且可以被for循环遍历,好处就是可以节省内存空间。
以文件句柄举例:
1 f = open('log',encoding='utf-8',mode='w')2 print('__iter__' indir(f))3 print('__next__' in dir(f))
View Code
结果:
(3)将我们常见的数据类型变成迭代器:
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__' indir(l1))14 print('__next__' indir(s1))15 print('__next__' indir(t1))16 print('__next__' indir(set1))17 print('__next__' in dir(dict1))
View Code
结果:
(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、判断是否是可迭代对象的第一种方法:
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__' indir(l))9 print('__iter__' indir(s))10 print('__iter__' indir(t))11 print('__iter__' indir(set))12 print('__iter__' indir(dict))13 print('__iter__' in dir(f))
View Code
第二种方法:
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))
View Code
b、判断是否是迭代的第一种方法:
print('__next__' in dir(f))
第二种方法:
from collections import Iterator
print(isinstance(f,Iterator))
2、生成器:
生成器其实就是迭代器,可以被for循环遍历的一种函数,由于是是函数,所以会有返回值,但是在生成器里面不会用return返回结果,而是使用yield关键字去返回结果,yield每次都能返回一个或多个值,每遇到一个yield关键字时,函数就会挂起,下次执行时就会从它当前位置继续往下执行。
生成器格式:
1 deffunc1():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) #
13
14 如果想取到函数的执行结果的话必须像迭代器一样使用next()方法:15 print(next(g))16 print(next(g))17 print(next(g))
View Code
结果:
PS:当然生成器的取值方式是和迭代器一样的,不止是next一次次的去取,也可以使用while循环和for循环去取。
send取值:
send取值和next取值的方式是一样的,不同的是,send在取下一个值时可以给上一个yield赋值,但是,send不能用于取第一个值,而且也不能给最后一个yield赋值。
示例:
deffunc1():print('one')
num= yield 1
print(num)print('two')yield 2
print('three')yield 3g=func1()print(next(g))print(g.send(123)) #123传给了num
print(next(g))
View Code
结果:
取值第一个值是用send取,结果报错:
1 deffunc1():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))
View Code
结果:
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))
结果: