一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天
生成器和迭代器
生成器(generator)
定义:在Python中,这种一边循环一边计算的机制,称为生成器:generator
- 得到生成器地方式
- 通过列表推导式得到生成器
# 得到一个生成器
g = (x*3 for x in range(10))
print(type(g))
# 方式1:通过调用__next__()来获得下一个元素
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__()) #每次调用一次出一个结果
# 方式2:通过调用自带的next()函数 系统内置函数(放的是生成器的内置对象)
print(next(g))
print(next(g))
print(next(g)) #同样的也是每次运行一次出一次结果
若调用越界了,这时就会抛出StopIteration的异常,这时我们就得用异常处理来解决该问题
g = (x*3 for x in range(10))
while True:
try:
print(next(g))
except:
print('没有更多元素了!')
break
- 借助函数来得到生成器
- 定义一个函数,函数中有yield关键字
- 单纯调用函数接收到的结果是一个生成器的地址
- 和上面的方法一样都是用next()来得到结果
def func():
n = 0
while True:
n += 1
yield n
next(func())
func.__next__()
在这里我们可以把yield理解为retrun()和暂停的作用(return了,但没完全retrun)
- send方法
def gen():
i = 0
while i < 0:
temp = yield i
print(temp)
i += 1
g = gen()
g.send(None)
print(g.send('haha'))
print(g.send('23333'))
注意:每次向生成器中传值,然后第一次调用send函数只能传None(因为第一次生成器运行时会在yield暂停,而此时传入其他值接受不了,只能传入None)
应用多任务
进程>线程>协程
示例:
有一个程序员上班想摸鱼,于是协程的想法在他脑中冒出
def demo(n):
for i in range(1,n)
print('正在写{}段代码'.format(i))
yield None
def music(m):
for i in range(1,m)
print('正在听第{}首歌'.foemat(i))
yield None
n1 - demo(5)
n2 = music(5)
while True:
try:
new(n1)
new(n2)
except:
pass
只有上面这样利用协程老板才不会发现他在摸鱼
迭代器
迭代时访问集合元素的一种方式,迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合第一个元素开始访问,知道所有元素都被访问完结束,迭代器只能往前不能往后(可迭代的定义)
可迭代的对象
- 生成器
- 元组,列表,集合,字典,字符串
如何判断是否是可迭代的
- isinstance
from collection import Iterable
list1 = [1,2,3,4]
f = isinstance(list1,Iterable)
print(f)
注意:可迭代的 ≠ 迭代器
可以被next()函数调用并返回下一个值的对象称为迭代器:Iterator
- 把可迭代的转变为迭代器:iter()
list = [1,2,3,4,5]
list1 = iter(list)
注意:生成器一定是迭代器,但迭代器不一定是生成器