目录
何为迭代?
可迭代对象
迭代器对象
迭代器的优缺点
优点
缺点
for循环底层原理
迭代取值与索引取值对比
迭代器即用来迭代取值的工具,而迭代是重复反馈过程的活动,其目的通常是为了逼近所需的目标或结果,每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值,单纯的重复并不是迭代.
迭代其实就是更新换代, 每一次结果都是基于上一次的结果, eg: 游戏版本更新, 每次更新都是基于上一版本的迭代.
单纯的循环并不是迭代
import time
while True:
print(123)
time.sleep(0.1)
迭代
# 属于迭代
n = 1
while True:
print(n)
n += 1
迭代取值
# 迭代取值
l1 = [11, 22, 33, 44, 55]
n = 0
while n < len(l1):
print(l1[n])
n += 1
通过索引的方式进行迭代取值,实现简单,但仅适用于序列类型:字符串,列表,元组。对于没有索引的字典、集合等非序列类型,必须找到一种不依赖索引来进行迭代取值的方式,这就用到了迭代器。
要想了解迭代器为何物,必须事先搞清楚一个很重要的概念:可迭代对象(Iterable)。从语法形式上讲,内置有__iter__方法的对象都是可迭代对象,字符串、列表、元组、字典、集合、打开的文件都是可迭代对象:
大白话理解就是数据可以通过点的方式点出来__iter__
迭代器对象 即可迭代对象调用__iter__方法之后生成的结果就是迭代器对象, 迭代器对象的特征
为含有__iter__方法和__next__方法. 迭代器对象能够极大的节省存储空间
调用__next__方法即可进行迭代器对象取值 如果取完了则会直接报错!!!
ps:开辟了一种不需要索引取值的方式(for循环底层依据的就是迭代器对象)
'''有了迭代器对象才出现了针对字典和集合的迭代取值操作'''
迭代器对象补充说明
1.有很多双下方法其实都有简便写法 但不是全部
"""
__方法名__ 等价 方法名()
最为常见的两个是
__iter__ iter()
__next__ next()
"""
2.有一些可迭代对象本身也是迭代器对象>>>:文件对象
3.可迭代对象调用一次__iter__方法编程迭代器对象 如果继续调用 结果还是迭代器对象本身.
# s = 'yietong'
# print(s.__iter__()) #
# print(iter(s)) #
res = s.__iter__()
res1 = s.__iter__().__iter__().__iter__()
print(res, res1)
#
4.迭代取值的要求
print(s.__iter__().__next__()) 每次先产生一个新的迭代器对象然后取值
s = 'yietong'
res = s.__iter__()
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
# y
# i
# e
# t
# o
# n
# g
基于索引的迭代取值,所有迭代的状态都保存在了索引中,而基于迭代器实现迭代的方式不再需要索引,所有迭代的状态就保存在迭代器中,然而这种处理方式优点与缺点并存:
1、为序列和非序列类型提供了一种统一的迭代取值方式。
2、惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用__next__来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
1、除非取尽,否则无法获取迭代器的长度
2、只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。
for 变量名 in 可迭代对象:
循环体代码
1.会将in后面的数据调用__iter__()变成迭代器对象
为什么文件对象也可以for循环 因为文件本身就是迭代器对象 再次调用不变
2.针对产生的迭代器对象依次调用__next__()方法迭代取值
3.当值取完之后 会自动处理报错并退出循环.
需求:不依赖于for循环 完成对列表元素的取值
l1 = [11,22,33,45,66,77]
res = l1.__iter__()
while True:
print(res.__next__())
'''
11
22
33
45
66
77
Traceback (most recent call last):
File "C:/me/JetBrains/pythonProject/迭代器/迭代器.py", line 185, in
print(res.__next__())
StopIteration
'''
for循环结合异常处理
res = 可迭代对象.__iter__()
while True:
try:
print(res.__next__)
except StopIteration as e:
break
1.索引取值
优势:可以反复获取相同的元素 并且没有固定的方向
劣势:只能支持有序的容器类型 无序的无法取值兼容性没有迭代取值高
2.迭代取值
优势:兼容所有的容器类型
劣势:取值的顺序永远都是从左往右 并且无法重复获取 取完就完了
# 真正底层的迭代取值后续可能很少用 一般都是for循环代替
"""
迭代器里面的东西是固定的 每取一个就会少一个 取完就空了
"""