迭代
通过for遍历访问一个列表或者容器里的所有元素,这个遍历我们就可以称之为迭代。
可以被for循环的都是可迭代的类型,可迭代类型内部一定有__iter__方法。
迭代器
每个可迭代对象内部都有__iter__方法,当可迭代对象执行了__iter__方法就成了一个迭代器
print([1, 2, 3].__iter__()) # 结果 <list_iterator object at 0x7f21fbd581d0
我们利用dir 来查看下迭代器 和可迭代对象之间有什么不同的方法
list1 = [1, 2, 3, 4, 5] iter1 = list1.__iter__() print(set(dir(iter1)) - set(dir(list1))) # 结果 {'__length_hint__', '__setstate__', '__next__'}
可以看到 迭代器 比 可迭代对象多了三个方法
# 查看迭代器内共有多少元素 print(iter1.__length_hint__()) # 指定迭代器从第几个元素开始迭代 iter1.__setstate__(2) for i in iter1: print(i) # 从迭代器中取下一个值 print(iter1.__next__()) print(iter1.__next__()) print(iter1.__next__())
注意:next方法会如果一直取值,当迭代器没有值可以取的时候,会抛出一个异常StopIteration,异常处理如下
while True: try: print(iter1.__next__()) except StopIteration: break
range()方法是什么类型
print("__iter__" in dir(range(1, 10))) # True print("__next__" in dir(range(1, 10))) # False
可以看出range内有iter方法,但是没有next方法,由此,range方法得到的是一个可迭代对象,而不是一个迭代器
from collections import Iterator print(isinstance(range(100000000), Iterator)) # 验证range执行之后得到的结果不是一个迭代器
生成器
迭代器的功能就是节省内存,为了实现这一功能,有的时候我们需要自己定义一个迭代器,我们自己定义的这个具有迭代器功能的就是生成器
实现:和函数定义一样,不同的是使用yeild语句返回结果而不是return,yield一次返回一个结果,返回之后挂起函数状态,下一次执行从该处继续执行,
可以说一个包含了yield关键子的函数就是生成器,调用生成器函数会返回一个生成器对象
用生成器写一个range()
def my_range(start, stop, step): n = start while n < stop: yield n n += step for i in my_range(1, 100, 3): print(i)