迭代器
什么是可迭代对象?
我们知道list、tuple、dict、set、
str 可以用for循环遍历,这种遍历称为迭代(Iteration),被遍历的list或tuple等被称为可迭代对象。
什么是迭代器( Iterator)
迭代器是一个具有迭代功能的对象,它从集合的第一个元素开始访问,直到所有的元素被遍历完,它有两个基本的方法iter()和next()。其中iter()用来创建迭代器对象,next()用于遍历对象的元素。
迭代器提供了一种不依赖索引取值的方式,适用于遍历元素比较多的集合,不会在内存中再占用一大块内存,而是随着循环每次生成一个,从而节省内存占用。
集合数据类型如 list 、 dict 、 str 等是可迭代的, 但不是迭代器 ,不过可以通过 iter() 函数获得一个 Iterator 对象。
#迭代器=iter(容器)
list01 = [1, 2, 3, 4, 5]
iterator = iter(list01)
在遍历字符串,列表或元组对象时经常会用到迭代器,使用next(),获取其中的所有语法。
next()函数不断返回下一个数据,直到没有数据时抛出StopIteration错误。
list02=[1,2,3]
it=iter(list02)
while True:
print(next(it))
#输出结果
1
2
3
Traceback(most recent call last):
File"func_1.py", line 55, in<module>
print(next(it))
StopIteration
可以使用isinstance()判断一个对象是否可迭代:
from collections.abc import Iterable
print(isinstance([1, 2, 3], Iterable)) # 输出True
自定义迭代器
自定义迭代器,需要再实现两个方法 iter() 与 next() 。
iter()方法返回迭代器对象本身,next()方法返回下一个元素。for语句就是通过__iter__()方法来获得迭代器对象,接着不停的调用迭代器对象的__next__()方法,循环遍历取值。
生成器
生成器是一个函数,普通函数用 return 返回一个值,如果一个函数用yield返回值,就叫生成器函数。函数被调用时会返回一个生成器对象。这个生成器对象自动实现了__iter__() 与 next() ,生成器是一种特殊的迭代器。
生成器函数和普通函数的区别:
普通函数遇到return语句或者最后一行语句就返回。而变成生成器函数,调用的时候返回的是生成器对象。在每次调用next()或用for语句进行下一次迭代时才执行,遇到yield语句停止,再次执行时从停止的地方继续执行,直到遇到下一个yield语句。
def func(n):
for i in range(n):
yield i
#调用该函数
func(5)
<generatorobjectfuncat 0x000001E76A903B48> #返回的是生成器对象
#查看该对象中包含的方法
print(dir(func(5)))
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
f=func(5)
print(next(f)) #0
print(next(f)) #1
使用生成器的好处
假设创建了一个包含1000个元素的列表,这1000个元素都放在内存中会占用很大的存储空间。而生成器并不是一上来就把所有值加载进内存,而是你要用几个元素,它才会把这些元素一个个读出来,大大节约了内存。
生成器表达式
有一种非常简便的方式创建生成器,就是生成器表达式。
生成器= (操作 for 元素 in 可迭代对象 )
list03=(x*2 for x in range(5)) #生成列表
for i in list03:
print(i) #输出0 2 4 6 8