1. 生成器
1. 列表生成式
对于一个列表,如果你想要把列表的每个元素进行*2的操作,要么是使用for循环进行操作,还有就是可以使用列表生成式
for 循环:
num = [1,2,3,4,5] num2= [] for n in num: n=n*2 num2.append(n)
print(num2)
列表生成式:
num = [1,2,3,4,5] num2 = [i * 2 for i in num] # 对于num中的i,每个i*2,放到新的列表中
num3 = [i *2 for i in num if i<4] # 还可以加判断,对于num中的i,如果i<4,就i*2,然后放到新列表中 print(num2)
print(num3)
2. 简单的生成器
生成器,就是将列表生成式的 [] 改成 () 就行。
num = (i * 2 for i in range(1,10)) print(num) # generator对象 print(num.__next__()) # 通过__next__()方法取值,一次取一个 print(next(num)) # 通过next()方法取值,一次取一个 for i in num: # 通过循环遍历,获取所有值 print(i)
3. 复杂的生成器
复杂的生成器。上面的生成器是很简单的,才能用列表生成式实现,但是如果复杂的呢,例如斐波拉契数列,就需要使用 yield 了
def fib(num): # 带有yield关键字,是生成器 n,a,b = 0,0,1 while n<num: yield b # 每次调用,执行到yeild就停止,相当于return b, # 下一次调用__next__方法时,从yield的下一行开始执行 a,b = b,a+b n+=1 return 'done.' '''注意,for循环遍历迭代器无法执行到这一句代码,只能通过异常处理捕获''' f = fib(10) print(f.__next__()) print(f.__next__())print('------------') # 遍历迭代器的内容:方法一,无法获取返回值(因为每次for循环,遇到yield都相当于return一个值,当最后一次yield时,整个函数就通过yield结束了,无法执行下面的语句,故无法获取真正的return语句) # for i in f: # print(i) # 遍历迭代器的内容:方法二,通过捕获异常获取返回值 while True: try: x = next(f) # 等同于 f.__next__() print(x) except StopIteration as e: # 通过异常处理获取返回值 print(e.value) # e的值是return的内容 break
3.通过yield给生成器传值
def consumer(name): print('%s来吃包子了!'% name) while True: baozi = yield print('%s包子被%s吃了!'%(baozi,name)) c = consumer('Wang') c.__next__() # 第一次执行迭代器,执行到yield停止,目的是执行:print('%s来吃包子了!'% name)
c.send('1个') # 给yield传递值,并从上次停止的地方(yield处)开始执行下面的代码
4. 生成器的并行
import time def consumer(name): print('%s来吃包子了!'% name) while True: baozi = yield print('%s包子被%s吃了!'%(baozi,name)) # c = consumer('Wang') # c.__next__() # 第一次执行迭代器,执行到yield停止 # c.send('1个') # 给yield传递值,并继续上次停止的地方开始执行 def maker(name): A = consumer('A') B = consumer('B') next(A) # A.__next__() ,执行生成器,遇到yield返回,目的是打印: %s来吃包子了! next(B) print('%s开始做包子了!'%name) for i in range(5): time.sleep(0.7) print('%s第%s笼做了10个包子!' %(name,i+1)) A.send('5个') B.send('5个') maker('C')
2. 迭代器
迭代对象: 能用for循环进行遍历的对象,都是迭代对象,可迭代的
迭代器: 凡是能用next调用的对象,才是迭代器,所以生成器是迭代器,但是迭代器不一定非得是生成器
from collections.abc import Iterable from collections.abc import Iterator # 判断是否可迭代 print(isinstance('aaaa',Iterable)) print(isinstance([1,2,3],Iterable)) print(isinstance({1:2,3:4},Iterable)) print(isinstance((1,2,3),Iterable)) # 判断是否是迭代器 print(isinstance('aaaa',Iterator)) print(isinstance([1,2,3],Iterator)) print(isinstance({1:2,3:4},Iterator)) print(isinstance((1,2,3),Iterator)) print(isinstance((x*1 for x in range(10)),Iterator)) # 转换成迭代器 a = iter([1,2,3,4,5]) print(next(a)) print(next(a))