python——生成器和迭代器的概念

一、生成器(generator)

1.1 概念理解

作用:生成器主要用于提高代码效率、节约内存空间,在python中,没有被调用的对象会被销毁。

# 之前学过列表生成式
s = [i for i in range(10)]
print(s)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 创建一个生成器 
s = (i for i in range(10))
print(s)  # <generator object <genexpr> at 0x000001BF5E2107B0>

与列表相比,列表创建的10个数值都在内存中开辟了空间,而生成器只有当前调用才创建的一个内存空间。打个比方,列表相当于10道菜,而生成器则是能做这10道菜的一个厨师,当被调用时,就会制作其中一个菜品。

1.2 创建与调用生成器

1.2.1 创建生成器

#创建生成器的两种办法
# 1. 生成器表达式
g = (i for i in range(1,6))
print(s)  # <generator object <genexpr> at 0x000002010C5D07B0>

# 2. 使用 yield 关键字
def func():
    print('f1')
    print('f11')
    yield 1
    print('f2')
    yield 2


print(func())  # <generator object func at 0x0000014F984207B0>
#注意:func()才是生成器对象,而不是func

1.2.2 生成器调用

在版本python2中使用语法:

生成器对象.__next__()

在版本python3中还可以使用语法:

next(生成器对象)

# 生成器的调用语法
s = (i for i in range(3))

# print(s.__next__())  # 版本python2 调用生成器的语法
print(next(s))  # 0
print(next(s))  # 1
print(next(s))  # 2
# print(next(s))  # 报错

 每一次调用生成器,会返回单个值,直到生成器中没有值了,程序就会报错。

# yield创建的生成器调用
def f():
    print('f1',end=' ')
    print('f11')
    yield 1
    print('f2')
    yield 2

j = 0
for i in f():
    print(i,'-->',j)
    j +=1

============
f1 f11  # 第一次调用输出了f1和f11 
1 --> 0 # 第一次调用结束还输出了1
f2      # 第二次调用输出f2
2 --> 1

yield 关键字,函数调用时一旦执行到该行,就会停止执行并且返回yield的值,并且存档,下一次调用函数的时候,从该存档处继续执行。

yield 和return有一定区分:

return:在函数中返回某个值,然后函数结束运行,一般没有返回值类型,就不用写return
yield:带yield的函数是一个生成器,在函数内部碰到这个yield的时候,函数会返回某个值,当下次执行函数后,会在上次停留的位置继续运行。

1.3 可迭代对象

从现象上看,能使用for循环的都是可迭代对象;

从本质上看,存在内置函数__iter__方法的是可迭代对象。

# 可迭代对象的特点
# 1.能用for循环
# 2.内置函数存在 __iter__()
l = [2, 4, 6]
for i in l:
    pass
l.__iter__()

t = (1, 2, 3)
for i in t:
    pass
t.__iter__()

d = {'name': 'huoying'}
for i in d:
    pass
d.__iter__()

注意:

  1. 生成器是可迭代对象;
  2. 迭代器也是可迭代对象;
  3. 可迭代对象不一定是迭代器。

二、迭代器(iterator)

2.1 概念理解

作用:提供一种有效的方式来遍历数据集合。

如何分辨迭代器?迭代器的两个必存在的特点:

  1. 有iter方法(iter方法作用是返回一个迭代器)
  2. 有next()方法
l = [1,2,3] 
# l.__next()__ # 列表没有next()方法
d = iter(l) # iter()方法将返回迭代器d
print(d)
print(next(d))

for循环内部本质

  1. 调用可迭代对象的iter方法返回一个迭代器
  2. 不断的调用迭代器的next方法
  3. 处理异常
arr = iter([1,2,3])
for i in arr:
    print(i)

相较于while循环,while循环不能自动处理异常

# while不处理异常的话,程序会报错,因为第4次循环,迭代对象已经没有内容了
arr = iter([1,2,3])
while True:
    print(next(arr))

# 加入处理异常try功能
arr = iter([1, 2, 3])
while True:
    try:
        print(next(arr))
    except StopIteration:
        break

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值