可迭代对象iterable
迭代是遍历元素的一种方式
定义
可以被 for ... in ...
循环遍历的对象,就是可迭代对象
利用模块collections判断是否可迭代 Iterable(类)
自定义可迭代对象
任何一个对象, 只要具备
__iter__
魔法方法,这个对象 就是可迭代对象
from collections.abc import Iterable
class MyIterable():
"""
自定义一个类, 类 具备 __iter__ 魔法方法
"""
def __iter__(self):
pass
a = MyIterable() # 由 类 去 实例化一个对象
flag = isinstance(a, Iterable) # 判断对象a 是否为 可迭代对象
print(flag) # flag为True,a 是 可迭代对象, flag为False, a不是可迭代对象
迭代器(iterator
)
定义
只要 任何一个对象, 具备 iter 和 __next__这两个魔法方法, 这个对象就是迭代器对象
任何一个迭代器对象, 肯定是 可迭代对象
判断方式
from collections.abc import Iterator
alist = [1, 2, 3, 4] # 列表、数组、字符串 只是 可迭代对象, 并不是 迭代器对象
if isinstance(alist, Iterator) is True:
print("alist是迭代器对象")
else:
print("alist不是迭代器对象")
获取迭代器的3种方式:
1.利用for循环获取迭代器数据
2.利用while循环和异常捕获
3.利用list、tuple类型转换
for循环本质
1.利用iter函数得到函数 2.利用next函数依次取值 3.捕获异常
自定义迭代器
定义迭代器的三步:
1.定义一个类
2.在类中实现__iter__,__next__方法(iter方法里返回自身,即return self)
(__del__魔法方法,当对象被删除时,自动执行该方法)
3.初始化实例属性
迭代器数据只能取一次,迭代器只能前进,不能后退
from collections.abc import Iterator
class MyIterator():
"""
自定义类, 具备 __iter__ 和 __next__ 魔法方法
"""
def __iter__(self):
"""
返回迭代器自身即可
"""
pass
def __next__(self):
"""
要么 每次 返回一个值,
要么 值已经 返回完了, 需要 抛出 StopIteration(停止迭代异常)
"""
pass
m = MyIterator() # 实例化对象,m对象就具备 __iter__ __next__
flag = isinstance(m, Iterator) # 判断m 是否 为 迭代器对象
print(flag) # flag为True, m就是迭代器对象, flag 为False,m就不是迭代器对象
迭代器案例
迭代器实现n以内的奇数
# n以内的奇数 1 到 n 结束
class OddNumber(object): # 类名 遵循 大驼峰命名法
def __init__(self, n):
self.a = 1 # 代表迭代器数字从 1 开始
self.n = n
def __iter__(self):
"""返回迭代器对象本身"""
return self
def __next__(self):
if self.a < self.n:
"""满足条件,每次返回值"""
r = self.a # 先保存
self.a += 2 # 后变化
return r # 最后返回
else:
"""不满足条件,抛出异常"""
raise StopIteration
o = OddNumber(20)
for i in o:
print(i)
迭代器实现斐波那契数列
class Fibonacci(object):
def __init__(self):
self.a = 1
self.b = 1
self.n = 0 # 代表已经返回多少项数据
def __iter__(self):
return self
def __next__(self):
if self.n < 10:
r = self.a
self.b, self.a = self.a + self.b, self.b # 斐波那契数列本身的变化
self.n += 1 # 代表已经返回一个值, n就加1
return r
else:
raise StopIteration
f = Fibonacci()
for i in f:
print(i)
迭代器实现列表遍历
# 自定义一个迭代器,并且重写iter()和next()方法,
# 对一个列表alist = [11,22,33,44,55,66,77,88,99]进行迭代
class ListIterator(object):
def __init__(self, alist):
"""初始化属性"""
self.alist = alist # 先将列表 通过 参数 传入 对象内部
self.i = 0 # 代表 列表 中元素的下标
def __iter__(self):
return self
def __next__(self):
if self.i < len(self.alist):
r = self.alist[self.i] # 通过下标 将 列表中的 值取出
self.i += 1 # 下标后移
return r
else:
raise StopIteration
l = ListIterator([11, 22, 33, 44, 55, 66, 77, 88, 99]) # l本身就是迭代器对象,不需要iter()转换
while True:
try:
i = next(l) # next()函数 实际 调用 对象 中的 __next__() 魔法方法, 取值
print(i)
except StopIteration:
break # 出现异常,数据已经取完, 结束循环
# 本身是可迭代对象, 不是 迭代器, 通过 iter()函数转换,得到 迭代器
# 本身就是 迭代器, 不需要iter()函数转换