十四:生成器函数和迭代器函数

一:列表生成器:就是在列表内部使用一条语句来生成一个列表。

example 1: 列表生成器示例

 1 # 列表生成: 把可迭代对象中的每一个元素进行操作的结果放在列表中
 2 
 3 s = [x * x for x in range(5)]
 4 
 5 
 6 # 操作也可以是一个函数
 7 
 8 def f(x):
 9     return x * x
10 
11 s = [f(x) for x in range(5)]

二:生成器函数:生成器函数与一般的函数有一个显著的不同,对于一般的函数,会把所有的结果一次性返回,被存储到内存中,对于数据量比较大的结果如果一次性全部返回会占用非常大的内存空间;但是生成器只是返回一个生成器对象,如果想要返回结果,只能调用内部的 next()方法进行操作,并且每次只能返回一个结果,对于大量的 next()操作可以使用 for 循环来实现。

example 2: 列表生成器创建生成器

1 s = (x * 2 for x in range(10))
2 print(s)    # <generator object <genexpr> at 0x00EEEA50>
3 
4 for i in s: # 生成器是一个可迭代对象
5     print(i)
6 
7 print(next(s))   # 等价于 s.__next__() in py2

三:生成器的创建:创建一个生成器有两种方式,一种就是利用列表生成式来创建一个元祖,这个元祖就是一个生成器;另外一种方式就是使用yield来创建一个生成器。

example 3:yield 创建生成器示例:

 1 # 生成器的创建方式:yield 关键字实现
 2 
 3 # def foo():   # 生成器函数
 4 #     print('ok')
 5 #     yield 1     # 类似于一般函数的 return ,返回值为 1,下次从这个断点开始往下执行
 6 #     print('ok2')
 7 #     yield 2
 8 #
 9 # f = foo()   # f 是一个生成器
10 # print(f)
11 #
12 # for i in f :  #生成器本身就是一个可迭代对象
13 #     print(i)   # 内存中始终只存储有一个元素,py垃圾回收机制

四:可迭代对象:就是内部有 iter() 方法的对象,比如,列表,元祖,字典,都是可迭代对象。

example 4: 可迭代对象

1 # 什么是可迭代对象? 内部有iter方法,列表,元祖,字典都是可迭代对象
2 
3 L= [1,2,3]
4 
5 L.__iter__()

五:利用 yield 来实现斐波那契数列,每个元素一个一个生成,并不是一下子都执行出来存放在内存中

example 5: 利用yield 来实现 斐波那契数列

 1 # 斐波那契数列:0 1 1 2 3 5 8 13
 2 
 3 # def fib(max):
 4 #     n,befor,after = (0,0,1)
 5 #     while n<max:
 6 #         yield befor     # 通过调用 next()一个一个的返回
 7 #         befor,after = after,befor + after
 8 #         n += 1
 9 #
10 # f = fib(8)
11 # print(f)
12 
13 # print(next(f))   # 0
14 # print(next(f))   # 1
15 # print(next(f))   # 1
yield 实现 Fib 数列

六:生成器中的传值操作:send():可以利用该函数传入值,即把该值传送给 yield 的值

example 6:生成器传值

 1 def bar():
 2     print('ok1')
 3     count = yield 1
 4     print(count)
 5 
 6     yield 2
 7 
 8 f = bar()
 9 print(f)
10 
11 next(f)  # 打印 ok1, yield返回
12 # s = f.send(None)  # 第一次send 只能传入None ,等同于 next(f)
13 ret = f.send('eee')   # 把‘eee’发送到上次断点处,赋值给 count ,然后打印
14 print(ret)   # 将整个生成器函数的返回值 返回给调用者,赋值给 ret

七:迭代器:生成器都是迭代器,迭代器不一定都是生成器。可迭代对象通过内置的 iter() 方法可以转化为一个迭代器。迭代器同样可以通过调用 next()方法。

1 # 生成器都是迭代器,迭代器不一定是生成器
2 
3 L= [1,2,3,4]
4 d = iter(L)
5 print(d)   # <list_iterator object at 0x017873F0>
6 
7 print(next(d))  # 1
8 
9 for i in [1,2,3]:  # 1,调用可迭代对象的 iter 方法 返回一个迭代器对象,2,不断调用迭代器对象的 next 方法 3,处理Iterorstop异常

猜你喜欢

转载自www.cnblogs.com/zpcoding/p/9480768.html