1. 迭代器
先区分两个概念:可迭代对象(iterable)、迭代器(iterator)
1️⃣可迭代对象(iterable)
概念:能被 for 循环遍历的对象,就是可迭代对象(iterable)
如下这些都是可迭代对象(iterable):
names = ['张三', '李四', '王五']
citys = ('北京', '上海', '深圳')
msg = 'hello'
for item in names:
print(item)
如下这些不是可迭代对象(iterable):
age = 10
def test():
pass
for item in test:
print(item)
endregion
可迭代对象都拥有__iter__方法。
names = ['张三', '李四', '王五']
citys = ('北京', '上海', '深圳')
msg = 'hello'
age = 10
def test():
pass
names.__iter__()
citys.__iter__()
msg.__iter__()
print(hasattr(names, '__iter__'))
print(hasattr(citys, '__iter__'))
print(hasattr(msg, '__iter__'))
print(hasattr(age, '__iter__'))
print(hasattr(test, '__iter__'))
2️⃣迭代器(iterator)
调用__iter__方法会得到:迭代器(iterator)
- 备注1:__iter__是一个魔法方法,当调用iter函数时,__iter__会自动调用。
- 备注2:可迭代对象.__iter__() 等价于: iter(可迭代对象)。
- 备注3:如果iter(obj)能得到一个迭代器(iterator),那obj就是可迭代对象。
names = ['张三', '李四', '王五']
citys = ('北京', '上海', '深圳')
msg = 'hello'
print(names.__iter__())
print(citys.__iter__())
print(msg.__iter__())
print(iter(names))
print(iter(citys))
print(iter(msg))
迭代器(iterator)拥有__next__方法,每次调用都会根据当前的状态,返回下一个元素。
- 备注1:迭代器.__next__() 等价于 next(迭代器)。
- 备注2:当所有元素全都取出后,若继续调用__next__,Python会抛出StopIteration异常。
names = ['张三', '李四', '王五']
it = iter(names)
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(next(it))
print(next(it))
print(next(it))
print(next(it))
编写for循环遍历names列表
names = ['张三', '李四', '王五']
for item in names:
print(item)
for循环背后的逻辑
names = ['张三', '李四', '王五']
# 1️⃣调用【可迭代对象的__iter__方法】获取到一个迭代器(iterator)
it = iter(names)
# 2️⃣开启一个无限循环
while True:
try:
# 3️⃣调用__next__方法,获取下一个元素
item = next(it)
print(item)
except StopIteration:
# 4️⃣捕获 StopIteration 异常,随后结束循环
break
迭代器(iterator)也拥有__iter__方法,并且其返回值是迭代器自身。
这么设计的原因:让 for 循环也能遍历迭代器(即:为了让 iter(迭代器) 不出错)。
names = ['张三', '李四', '王五']
it = iter(names)
print(it)
result = iter(it)
print(result)
x = iter(result)
print(x)
it = iter(names)
for item in it:
print(item)
迭代器协议:一个对象如果同时满足如下规范,那该对象就是一个迭代器:
- 能被iter()接受。
- 能被next()一步一步取值。
迭代器是一次性的,状态只会向前推进,且不会自动重置(迭代器在遍历的过程中会被“消耗”)。
names = ['张三', '李四', '王五']
it1 = iter(names)
it2 = iter(names)
print(it1)
print(it2)
print(next(it1))
print(next(it1))
print(next(it1))
print(next(it1)) # 此行代码会抛出异常,因为此时迭代器已经被耗尽了
# 如想重新依次获取元素,需要使用新的迭代器it2
print(next(it2))
print(next(it2))
print(next(it2))
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END












请登录后查看评论内容