迭代器和生成器的区别

迭代器

定义:
对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的.在后台for语句对容器对象调用iter()函数,iter()是python的内置函数,且会返回一个定义了next()的方法的迭代对象,它在容器中逐个的访问容器内的元素.有后续的元素的时候,next()会抛出一个StopIteration异常,通知for语句循环的结束.
额外补充:
1.迭代器协议,对象需要提供next()方法,要么返回迭代中的下一项,要么就引起一个StopIteration异常,终止迭代.
2.可迭代对象:实现了迭代器协议对象.list,tuple,dict都是Iterable(可迭代对象),但不是迭代器对象(Iterator).但可以使用内建函数iter(),将这些都变成Iterable(可迭代器对象).
3.for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束.
Python自带容器对象案例:

lst = [1,2,3]
# 使用iter()函数
iter_name = iter(lst)
print(iter_name) # 结果是一个列表list的迭代器<list_iterator object at 0x0000017B0D984278>
print(next(iter_name))
print(next(iter_name))
print(next(iter_name))
print(next(iter_name)) # 超出范围,没有迭代的下一个元素抛异常
'''
# Traceback (most recent call last):
# File "Test07.py", line 32, in <module>
# StopIteration
'''

生成器

返回数据需要使用到yield语句,每次next()被调用的时候,生成器会返回它脱离的位置(记忆语句最后一次执行的位置和所有的数据值)

作用:
延迟操作,在需要的时候才会产生结果,并不是立即产生结果.高效,可以节省cpu和内存(RAM)如果构造一个列表只是为了传递给别的函数,比如传递给tuple()或者set(),那就用生成器表达式代替.

b = [4,5,6,7,8]
v = tuple(a for a in b)
print(v)
# 结果是直接变成了(4,5,6,7,8)
# python内置的一些函数,可以识别是生成表达式,外面有一对小括,就是生成器.
res = sum(a for a in range(3))
print(res)

总结:
生成器能够做迭代器所做的所有事,而且因为自动创建iter()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存.除了创建和保持程序状态的自动生成,当发生器终结时,还会自动跑出StopIteration异常.

posted @ 2019-12-16 09:45  Huise.J  阅读(323)  评论(0编辑  收藏  举报