为什么学习迭代器
如何for循环自定义实例对象
class Student:
def __init__(self):
self.students = []
def add_student(self, name, age):
self.students.append({
"name": name,
"age": age
})
s = Student()
s.add_student('小明', 23)
s.add_student('小黑', 20)
# 如何实现for循环自定义实例对象?
for item in s:
print(item)
# 报错
TypeError: 'Student' object is not iterable
什么是迭代?
迭代是访问集合元素的一种方式
# 字符串
my_str = 'hello'
for i in my_str:
print(i)
# 列表
my_list = [1,2,3,4]
for i in my_list:
print(i)
可迭代对象
可以被for-in遍历的都是可迭代对象
验证数据类型是否可以被迭代
from collections.abc import Iterable
# True 字符串
print(isinstance('12', Iterable))
# True 列表
print(isinstance([1,2], Iterable))
# True 元组
print(isinstance((1,2), Iterable))
# True 集合
print(isinstance({1,2}, Iterable))
# True 字典
print(isinstance({'name':'alex'}, Iterable))
# False 整数
print(isinstance(1, Iterable))
# False浮点数
print(isinstance(1.1, Iterable))
迭代器
迭代器是一个可以记住遍历的位置的对象。迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
可迭代对象的本质
可迭代对象进行迭代的过程,发现每迭代一次都会返回对象中的下一条数据,一直向后直到取完所有数据。
在每一次迭代过程中需要有一个『东西』来记住访问到第几条数据了,这个『东西』被称为迭代器(Iterator)
获取可迭代对象的迭代器
通过
iter()
能够得到一个可迭代对象的 迭代器
from collections.abc import Iterator
nums_list = [11, 22, 33, 44]
# 提取迭代器
nums_iter = iter(nums_list)
print(f"nums_list: {type(nums_list)}") # nums_list: <class 'list'>
print(f"nums_iter: {type(nums_iter)}") # nums_iter: <class 'list_iterator'>
print("nums_list", isinstance(nums_list, Iterator)) # nums_list False
print("nums_iter", isinstance(nums_iter, Iterator)) # nums_iter True
获取迭代器数据
通过
iter()
能够得到一个可迭代对象的 迭代器,可以通过next()
函数多次提取迭代器中的数据
nums_list = [11, 22, 33, 44]
# 提取迭代器
nums_iter = iter(nums_list)
print(next(nums_iter))
print(next(nums_iter))
print(next(nums_iter))
print(next(nums_iter))
11
22
33
44
StopIteration异常
可迭代对象,我们可以通过
iter()
函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()
函数来获取下一条数据
nums_list = [11, 22]
# 提取迭代器
nums_iter = iter(nums_list)
print(next(nums_iter))
print(next(nums_iter))
print(next(nums_iter))
11
22
# 取不到之后会报StopIteration错误
Traceback (most recent call last):
File "提取可迭代对象的迭代器.py", line 19, in <module>
print(next(nums_iter))
StopIteration
实现for循环
for循环的过程就是通过iter()提取可迭代对象的迭代器,然后通过next提取数值,直到StopIteration异常抛出后停止迭代
nums_list = [11, 22]
# 提取迭代器
nums_iter = iter(nums_list)
while True:
try:
print(next(nums_iter))
except StopIteration as e:
print(f"e: {e}")
break
11
22
33
44
e:
自定义"迭代器"
__iter__方法
拥有
__iter__
的对象一定是可迭代对象
from collections.abc import Iterable
class MyList1:
pass
class MyList2:
def __iter__(self):
pass
m1 = MyList1()
m2 = MyList2()
# 检测是否是[可迭代对象]
print(isinstance(m1, Iterable)) # False
print(isinstance(m2, Iterable)) # True
__next__方法
在使用next()函数的时候,就是调用迭代器的
__next__
方法。一个类实现了
__iter__
和__next__
方法,生成的对象就是迭代器
from collections.abc import Iterable, Iterator
class MyIterable:
def __iter__(self):
# 当使用iter()函数时,会自动执行类中的__iter__方法,返回一个迭代器对象
print(f"MyIterable iter")
return MyIterator()
class MyIterator:
def __iter__(self):
pass
def __next__(self):
# 当使用next()函数时,会自动执行类中的__next__方法
print(f"MyIterator next")
my = MyIterable() # 获取可迭代对象
my_iter = iter(my) # 获取迭代器
# 可迭代对象不一定是迭代器
print("my是否是可迭代对象 ", isinstance(my, Iterable)) # True
print("my是否是迭代器 ", isinstance(my, Iterator)) # False
# 迭代器一定是可迭代对象
print("my_iter是否是可迭代对象 ", isinstance(my_iter, Iterable)) # True
print("my_iter是否是迭代器 ",isinstance(my_iter, Iterator)) # True
next(my_iter)
MyIterable iter
my是否是可迭代对象 True
my是否是迭代器 False
my_iter是否是可迭代对象 True
my_iter是否是迭代器 True
MyIterator next
验证list
from collections.abc import Iterable, Iterator
l = [1,2,3]
l_iter = iter(l)
print("l是否是可迭代对象 ", isinstance(l, Iterable)) # True
print("l是否是迭代器 ", isinstance(l, Iterator)) # False
print("l_iter是否是可迭代对象 ", isinstance(l_iter, Iterable)) # True
print("l_iter是否是迭代器 ",isinstance(l_iter, Iterator)) # True
l是否是可迭代对象 True
l是否是迭代器 False
l_iter是否是可迭代对象 True
l_iter是否是迭代器 True
案列
迭代器
class Student:
def __init__(self):
self.index = 0
self.students = []
def add_student(self, name, age):
info = {
"name": name,
"age": age
}
self.students.append(info)
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.students):
item = self.students[self.index]
self.index += 1
return item
self.index = 0
raise StopIteration
stu = Student()
stu.add_student('小明', 23)
stu.add_student('小黑', 20)
# 如何实现for循环自定义实例对象?
for item in stu:
print(item)
{'name': '小明', 'age': 23}
{'name': '小黑', 'age': 20}
可迭代对象+迭代器
class Student:
def __init__(self):
self.students = []
def add_student(self, name, age):
info = {
"name": name,
"age": age
}
self.students.append(info)
def __iter__(self):
return StudentIter(self)
class StudentIter:
def __init__(self, obj):
self.obj = obj
self.index = 0
def __iter__(self):
return self
def __next__(self):
# 判断可迭代对象的长度
if self.index < len(self.obj.students):
item = self.obj.students[self.index]
self.index += 1
return item
# 如果index超出长度,报StopIteration
self.index = 0
raise StopIteration
stu = Student()
stu.add_student('小明', 23)
stu.add_student('小黑', 20)
# 如何实现for循环自定义实例对象?
for item in stu:
print(item)
{'name': '小明', 'age': 23}
{'name': '小黑', 'age': 20}
标签:__,迭代,nums,self,iter,print
From: https://www.cnblogs.com/lxd670/p/17629277.html