迭代器和生成器
迭代器
- 迭代器是一个可以记住遍历的位置的对象。
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
- 迭代器只能往前不会后退。
isinstance
判断列表是否可迭代
isinstance(a,b)判断a是不是b类型
iter
字符串,列表或元组对象都可用于创建迭代器:
iter(a) 把可迭代的对象变为迭代器
next
next(a) 输出迭代器的一个值
from collections import Iterable
list1=[1,2,3,4,5]
print(isinstance(list1,Iterable))#True
print(isinstance(199,Iterable))#False
g1 = iter(list1)
#g2 = iter(111)#TypeError: 'int' object is not iterable
print(g1)#<list_iterator object at 0x000001CDD8D12DF0>
print(next(g1))#1
生成器
- 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
- 调用一个生成器函数,返回的是一个迭代器对象。
方式1 列表推导式
列表推导式
将旧列表推导出新列表
[表达式 for 变量 in 旧列表 if 条件]
la = [(i,j) for i in range(5) if i%2 == 0 for j in range(10) if j%3==0]
print(la)
#[(0, 0), (0, 3), (0, 6), (0, 9), (2, 0), (2, 3), (2, 6), (2, 9), (4, 0), (4, 3), (4, 6), (4, 9)]
lb = [[1,2,3],[4,5,6],[7,8,9],[1,3,5]]
lbb = [l[-1] for l in lb]
print(lbb)#[3, 6, 9, 5]
列表推导式得到生成器
将列表推导式的[]换成()
lb = [[1,2,3],[4,5,6],[7,8,9],[1,3,5]]
g = (l[-1] for l in lb)
print(type(g))#<class 'generator'>
方式2 借助函数完成
只要函数中出现yield,此函数变为生成器
- 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行
- next() 方法时从当前位置继续运行。
- 先运行函数到yield然后运行next()然后运行yield后面的内容
def func():
n=0
while True:
n+=1
print(n)
yield n #return n 并且暂停
g = func()
print(g)
#<generator object func at 0x000001DDF0C9DC10>
def fib(lenth):
a,b,n = 0,1,0
while n <lenth:
yield b
a,b = b,a+b
n +=1
return 'no' #得到StopIteration报错后的提示信息
f = fib(3)
print(next(f))
print(next(f))
print(next(f))
print(next(f))
"""
StopIteration: no
1
1
2
"""
输出生成器内容
g.next()
print(g.__next__())
调用空就产生异常
next(g)
print(next(g))
调用空就产生异常
send()
可以向每次生成器调用中向生成器中传值
第一次必须传None
g.send(None)
def func():
n=0
while n<5:
tmp = yield n #程序暂停到yield n tmp还没有获得赋值,等待生成器下一次启动才能获得赋值
print('tmp:',tmp)
n+=1
return 'no'
g = func()
print(g.send(None))
a = g.send('hhh')#启动生成器,对tmp赋值‘hhh’,a接受生成器生成的值
print('a',a)
b = g.send('111')
print('b',b)
"""
0
tmp: hhh
a 1
tmp: 111
b 2
"""