python生成器与迭代器_python之迭代器与生成器

1、迭代器

(1)可迭代对象:

什么是可迭代对象:

我们常见的数据量类型有list,str,tuple,set,dict以及文件句柄都是可迭代对象,因为他们中都包含了__iter__方法。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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

结果:

8f28200e08e469eb8392e296b3bc198a.png

PS:dir()是python内置的函数,可以打印出每个数据类型的所有可用方法

(2)迭代器:

什么是迭代器:

我们常见的数据类型也都只是可迭代对象而已,但是文件句柄却是一个迭代器,迭代器内部不仅包含了__iter__方法,还包含了__next__方法,并且可以被for循环遍历,好处就是可以节省内存空间。

以文件句柄举例:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 f = open('log',encoding='utf-8',mode='w')2 print('__iter__' indir(f))3 print('__next__' in dir(f))

View Code

结果:

e9fdbcace239a9350d299606eca215fc.png

(3)将我们常见的数据类型变成迭代器:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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

结果:

469fabe72afa2a96ae934bfb8158177d.png

(4)迭代器的取值方式:

迭代器的取值方式用的就是__next__方法,每next一次只取一个值,想取完所有值就要一直next,直到取完报StopIteration错误为止。

示例1:

l1 = l.__iter__()

print(l1.__next__())

print(l1.__next__())

print(l1.__next__())

print(l1.__next__())

结果:

e1e2ece16b72e5d863a656e5c67b8c88.png

示例2:

l1 = l.__iter__()

while True:

try:

print(next(l1)) ##next() == __next__()

except StopIteration:

break

结果:

ee365cf535b7b5167b56d70f31a9861d.png

示例3:

l1 = l.__iter__()

for i in l1:

print(i)

结果:

65434a15a74d8cf681b1393695f8e355.png

(5)判断是否是可迭代对象和迭代器的两种方法:

a、判断是否是可迭代对象的第一种方法:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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

第二种方法:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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关键字时,函数就会挂起,下次执行时就会从它当前位置继续往下执行。

生成器格式:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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

结果:

f68e384676b6df4bae08cfce16386fdd.png

PS:当然生成器的取值方式是和迭代器一样的,不止是next一次次的去取,也可以使用while循环和for循环去取。

send取值:

send取值和next取值的方式是一样的,不同的是,send在取下一个值时可以给上一个yield赋值,但是,send不能用于取第一个值,而且也不能给最后一个yield赋值。

示例:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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

结果:

ae63f22ea473303511e868f2e0fb7c11.png

取值第一个值是用send取,结果报错:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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

结果:

fe0d0d56a78c6aa3b6cc173b0eb47bdd.png

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)]

结果:

55420820910ff25a54b5f7044f40c106.png

列表表达式里还可以使用if判断:

比如判断打印大于5的每一期:

['python%s期' %i for i in range(1,11) if i > 5 ]

结果:

28ad7652afaa05c6c8e96e25d3e82ca9.png

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))

结果:

0510ce2c70a19e9409a15421975b3af9.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值