11 Python学习之迭代器和生成器

迭代器和生成器

迭代器

可迭代对象:

当一个对象能够一次返回一个成员,我们称这个对象为可迭代对象,常见的可迭代对象有:

  1. 顺序结构的有:str、list、tupe

  2. 无需结构的有:dict、set

  3. 类的对象拥有 __iter____getitem__ 方法

迭代器

当一个可迭代的对象,作为参数传递给内置函数 iter() ,就会返回一个迭代器对象

迭代器中必须包含__next__ 方法和__iter__ 方法

判断一个对象是不是迭代器:__next__ 方法和__iter__ 方法在不在dir(对象名)中,dir返回的是一个列表,如果这两个方法在这个列表中,那么该对象就是一个迭代器

注意:

如果读取数量超出了迭代器内的成员数量,会报StopIteration 错误;

例:

用while循环实现for循环效果:

li = [1, 2, 3, 4, 5]	# 可迭代对象--列表
obj = iter(li)          # 可迭代对象传入iter函数,生成迭代器并赋值给obj
while True:
    try:
        print(next(obj))        # 循环取出迭代器中的值
    except StopIteration:       # 取到最后一个会报错,捕获异常,并退出循环
        break

将可迭代对象转换成迭代器

语法:

iter(可迭代对象)

例1:

li = list(range(10))
ret = iter(li)
print(ret)
print(ret.__next__())
print(ret.__next__())
print(ret.__next__())
print(next(ret))

运行结果:

<list_iterator object at 0x7fea39ddf470>
0
1
2
3

可迭代对象和迭代器对比

可迭代对象 迭代器
占内存空间大(几百万的数据8G内存都能承受) 占内存小
速度快 速度慢
可返回 不可返回
可直观看到数据 数据不可见

生成器

在python社区,生成器与迭代器被看成是同一种,生成器的本质就是迭代器。唯一的区别:生成器是我们自己用Python代码构建的数据结构,迭代器是系统提供或转化得来的。

获取生成器的三种方式:

  1. 生成器函数
  2. 生成器表达式
  3. python内部提供的一些

yield

只要在函数中出现了yield,那么他就不是一个函数了,而是一个生成器

例1:

# 函数
def func(a, b):
   return a + b

ret = func(3, 5)
print(ret)					# 直接返回计算的结果 8

# 生成器
def func(a, b):
    yield a + b

ret = func(3, 5)
print(ret)					# 返回的是一个生成器,需要用next获取返回值
print(next(ret))			# 值是 8

例2:

生产汽车,按迭代对象的方式,就是一开始就全部生产出来,所用时间和内存都很大

用生成器,需要多少生产多少,所占内存和使用时间少

# 迭代对象方式
def get_func():
    li = []
    for i in range(50001):
        li.append(f"{i}号汽车")
    return li

ret = get_func()
print(ret)				# 一次创建5万个

# 生成器方式
def get_func():
    for i in range(50001):
       yield f"{i}号汽车"

ret = get_func()		# 此时,并不会创建,next调用时才创建
# 生产200辆
for _ in range(201):	# 创建200个
    print(next(ret))
    
# 再生产100辆
for _ in range(100):	# 创建100个
    print(next(ret))

yield from

yield from返回列表的每一个元素,相当于用了for循环用yield取出

例1:

def get_func():
    li = [1, 2, 3, 4, 5]
    yield from li				# 相当于 for i in li: yield i

ret = get_func()
print(next(ret))
print(next(ret))
print(next(ret))
print("执行了三次")
print(next(ret))

运行结果:

1
2
3
执行了三次
4

例2:

def get_func():
    li = [1, 2, 3, 4, 5]
    li2 = ['卫龙', '馒头', '花卷', '包子', '油条']
    yield from li
    yield from li2

ret = get_func()
for i in range(10):
    print(next(ret), end=' ')

运行结果:

1 2 3 4 5 卫龙 馒头 花卷 包子 油条

yield和return的区别

yield return
可以存在多个yield,取值时一个next对应一个yield 只能存在一个,遇到return函数就结束了
需要用迭代器获取返回的结果 直接返回结果

例1:

def func(a, b):
   yield a + b
   yield '返回a+b的结果'
   yield '结束'

ret = func(3, 5)
print(next(ret))
print(next(ret))
print(next(ret))

结果是:

8
返回a+b的结果
结束

posted @ 2020-08-03 18:11  爬坡的蜗牛  阅读(88)  评论(0编辑  收藏  举报