1、迭代
_iter_ | 对象方法 | 可迭代对象,返回迭代器 |
---|---|---|
__next_ | 对象方法 | 迭代器对象,返回迭代中每一步的运算 |
iter(object) | 内置函数 | 得到object的迭代器 |
next(object) | 内置函数 | 得到迭代器的下一步迭代结果 |
1.1可迭代对象(Iterable)
如果一个对象实现了__iter__方法,那么这个对象就是可迭代对象。
from collections.abc import Iterable, Iterator
class Color(object):
def __init__(self):
self.colors = ['red', 'white', 'black', 'green']
# 仅仅是实现了__iter__ 方法,在方法内部什么都不做
def __iter__(self):
pass
color_object = Color()
# 判断是否为可迭代对象
print(isinstance(color_object, Iterable)) # True
# 判断是否为迭代器
print(isinstance(color_object, Iterator)) # False
可迭代对象未必是迭代器,只是实现了_iter_方法,但是可迭代对象可以被for遍历,那是因为
for的工作原理:
1、使用iter获得可迭代对象的迭代器
2、反复对迭代器使用next方法
3、捕获StopIteration异常,退出循环
即for会使用iter去获得该可迭代对象的迭代器执行next方法遍历。
1.2迭代器
如果一个对象同时实现了__iter__方法和__next__方法,它就是迭代器。
迭代器一定是可迭代对象,因为迭代器要求必须同时实现__iter__方法和__next__方法, 而一旦实现了__iter__方法就必然是一个可迭代对象。但是反过来则不成立,可迭代对象可以不是迭代器。
from collections.abc import Iterable, Iterator
class Color(object):
def __init__(self):
self.colors = ['red', 'white', 'black', 'green']
# 仅仅是实现了__iter__ 方法,在方法内部什么都不做
def __iter__(self):
pass
def __next__(self):
pass
color_object = Color()
# 判断是否为可迭代对象
print(isinstance(color_object, Iterable)) # True
# 判断是否为迭代器
print(isinstance(color_object, Iterator)) # True
1.3迭代器工作原理
内置函数iter获得迭代器
iter函数的作用是从可迭代对象那里获得一个迭代器
from collections.abc import Iterator
lst_iter = iter([1, 2, 3])
print(isinstance(lst_iter, Iterator)) # Truefrom collections.abc import Iterator
lst_iter = iter([1, 2, 3])
print(isinstance(lst_iter, Iterator)) # True
使用内置函数next遍历迭代器
内置函数next的功能是从迭代器那里返回下一个值
from collections.abc import Iterator
lst_iter = iter([1, 2, 3])
print(next(lst_iter)) # 1
print(next(lst_iter)) # 2
print(next(lst_iter)) # 3
print(next(lst_iter)) # StopIteration
前3次调用next函数都能正常工作,第4次会抛出StopIteration异常,迭代器里已经没有下一个值了。
现在,让我们来做一个总结,遍历迭代器需要使用next方法,每调用一次next方法,就会返回一个值,没有值可以返回时,就会引发StopIteration异常。
为什么迭代器不能重复使用
iter函数每次会获得一个新的迭代器。
from collections.abc import Iterator
lst_iter = iter([1, 2, 3])
print(next(lst_iter)) # 1
print(next(lst_iter)) # 2 到了这一步,你想从头开始遍历,那么重新获得一个迭代器使用
lst_iter_2 = iter([1, 2, 3])
print(next(lst_iter_2)) # 1
print(next(lst_iter_2)) # 2
print(next(lst_iter_2)) # 3
1.4 自定义可迭代对象和迭代器
实现__iter__方法和___next___方法
如果可迭代对象实现了iter__方法,那么内置函数iter会调用对象的__iter__方法方法返回一个迭代器,由于Color类实现了__next__方法,因此Color的实例也是迭代器,在__iter__方法里返回self即可。
我们使用内置函数next对迭代器进行遍历,在这个过程中,是在调用迭代器的__next__方法, 内置函数的作用是返回迭代器的下一个值,这个功能的实现,我们需要放在__next__方法中。
class Color(object):
def __init__(self):
self.index = -1
self.colors = ['red', 'white', 'black', 'green']
def __iter__(self):
self.index = -1
return self
def __next__(self):
self.index += 1
if self.index >= len(self.colors):
raise StopIteration
return self.colors[self.index]
color_object = Color()
for color in color_object:
print(color)
2、生成器
⽣成器也是⼀种迭代器,但是你只能对其迭代⼀次。这是因为他们并没有把所有的值存在 内存中,⽽是在运⾏时⽣成值。
在待遍历列表占用空间非常大时候,或者用到的遍历项目并不多时候,使用迭代的方式需要将整个迭代变量放入内存中,就会非常占用资源和不合适。生成器据前面的元素推断后面的元素,一边循环一边计算的机制叫generator。generator保存的是算法,每次调用next()
,就计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration
的错误。
def intNum():
print("开始执行")
for i in range(5):
yield i
print("继续执行")
num = intNum()
和return 相比,yield 除了可以返回相应的值,还有一个更重要的功能,即每当程序执行完该语句时,程序就会暂停执行。不仅如此,即便调用生成器函数,Python 解释器也不会执行函数中的代码,它只会返回一个生成器(对象)。
要想使生成器函数得以执行,或者想使执行完 yield 语句立即暂停的程序得以继续执行,有以下 2 种方式:
- 通过生成器(上面程序中的 num)调用 next() 内置函数或者 next() 方法;
- 通过 for 循环遍历生成器。
#调用 next() 内置函数
print(next(num))
#调用 __next__() 方法
print(num.__next__())
#通过for循环遍历生成器
for i in num:
print(i)
标签:__,迭代,Python,self,生成器,iter,next,print
From: https://www.cnblogs.com/jzYe/p/17201496.html