在了解生成器与迭代器之前,先了解一下列表生成式
一、列表生成式
# 示例一
a = [x for x in range(1,11)]
print(a) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 示例二
def f(n):
return n * 2
b = [f(x) for x in range(1,11)]
print(b) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
列表生成式能够将列表中的内容展示出来,但是它有一个缺点,不管你取一个还是取全部,它都会将所有的数据都会生成出来,如果数据的量十分巨大的话,就会特别占用内存,所以,就有了生成器。
二、生成器 generator
生成器就是一个可迭代对象
1.通过()来创建生成器
a = (x for x in range(10))
print(a) # <generator object <genexpr> at 0x00000162C72D9548> 生成器对象以及它所在的地址
print(next(a)) # 它等价于print(a.__next__()) 注:在python2中,用s.next() 输出:0
print(next(a)) # 通过next来生成数据 输出:1
2.通过yeild创建
def a(): # 用def定义,利用关键字yield一次性返回一个结果,阻塞,然后重新开始
print('111')
yield 1 #yeild在这个地方,作用相当于return
print('bbb')
yield 2
b=a()
print(b) # <generator object a at 0x00000135D4F69548> 说明a()是一个生成器
for i in a(): # 可以通过for循环来取,把生成器中的内容一个一个取出来
# i = next(a())
print(i)
# 输出: 111
# 1
# bbb
# 2
3.通过yeild实现单线程下的伪并发状态
import time
def teacher(name):
print('%s 老师提前到教室' %(name))
time.sleep(2)
while True:
lesson=yield
if lesson == 0:
print('%s 老师开始上课了,上第%s节课' % (name,lesson))
time.sleep(2)
print('下课!!!!')
print('现在是课间休息时间')
time.sleep(2)
elif lesson == 1:
print('%s 老师开始上课了,上第%s节课' % (name, lesson))
time.sleep(2)
print('下课!!!!')
def student():
s = teacher('张')
s.__next__()
print('学生进教室中!!!!')
time.sleep(2)
for i in range(2):
if i == 0:
print('一共到了20个人')
time.sleep(2)
s.send(i) # send函数,将数据发送到生成器中
elif i ==1:
s2 = teacher('李')
s2.__next__()
print('现在来了40个学生')
time.sleep(2)
s2.send(i)
student()
# 输出: 张 老师提前到教室
# 学生进教室中!!!!
一共到了20个人
# 张 老师开始上课了,上第0节课
# 下课!!!!
# 现在是课间休息时间
# 李 老师提前到教室
# 现在来了40个学生
# 李 老师开始上课了,上第1节课
# 下课!!!!
三、迭代器
1.生成器都是迭代器,迭代器不一定是生成器
2.可作用于for循环的对象都是可迭代对象(iterable),例如:list,tuple,dict,set,str
3.可以被next()
函数调用并不断返回下一个值的对象称为迭代器
4.iterator计算是惰性的,需要返回下一个数据时,它才会计算,所以它可以表示自然数整体,如果使用list时无法储存的所有自然数的。
5.用isinstance判断一个对象是否为可迭代对象
from collections.abc import Iterator
from collections.abc import Iterable
a = [1,2,3,4,5,6]
print(isinstance(a,Iterator)) # 判断它是否时迭代器 False
print(isinstance(a,Iterable)) # 判断它是否时可迭代对象 True