迭代器

迭代器 : 将装有多个值的容器中的值通过循环反馈的方式逐个取出给外界的工具
为何用迭代器:提供一种通用的且不依赖于索的迭代取值方式
# 可迭代对象概念:
# 内置有__iter__()方法的对象都可称之为可迭代的对象,调用该方法返回迭代器对象
# 可迭代对象:str,list,tuple,dict,set,文件,迭代器对象,生成器,enumrate()
[].__iter__()
().__iter__()
{}.__iter__()
{1, }.__iter__()
​
# 迭代器对象:
# 1. 既内置有__next__方法的对象,执行迭代器__next__方法可以不依赖索引取值
# 2. 又内置有__iter__方法的对象,执行迭代器__iter__方法得到的仍然是迭代器本身
# ps:
# 1.迭代器对象一定是可迭代的对象,而可迭代的对象却不一定是迭代器对象
# 2.文件对象本身就是一个迭代器对象
​
st1 = {3, 5, 7, 1, 9}
iter_obj = st1.__iter__()  # 上一个迭代器对象迭代取值完毕后,就取空了,如果要再次取值,要重新生成迭代器对象
# 迭代器对象不能求长度(内部值的个数)
while True:
    try:
        ele = iter_obj.__next__()
        print(ele)
    except StopIteration:  # 捕获异常并处理
        # print("取完了")
        break
​
# for本质应该称之为迭代器循环
# 工作原理
# 1. 先调用in后面那个对象的__iter__方法,将其变成一个迭代器对象
# 2. 调用next(迭代器),将得到的返回值赋值给变量名k
# 3. 循环往复直到next(迭代器)抛出异常,for会自动捕捉异常然后结束循环
iter_obj = st1.__iter__()
for ele in iter_obj:
    print(ele)
​
print('===============================================')
for ele in st1:  # 1.自动完成 for ele in st1.__iter__():  2.自动完成异常处理
    print(ele)
​
# 迭代器总结:
# 优点:
#     1. 提供一种通用的且不依赖于索引的迭代取值方式
#     2. 同一时刻在内存中只存在一个值,更节省内存
​
# 缺点:
#     1. 取值不如按照索引的方式灵活,(不能取指定的某一个值,而且只能往后取)
#     2. 无法预测迭代器的长度

生成器

# 生成器:就是一个迭代器对象
# 包含yield关键字的函数就是生成器
# 该函数名()得到的就是生成器对象,且不会执行函数体
​
def g_fn():
    print(11111111111111)
    yield '结果1'
    print(222222222222222)
    yield '结果2'
g_obj = g_fn()
# 在函数内部执行一次,在遇到下一个yield时停止,且可以拿到yield的返回值
r1 = g_obj.__next__()
print(r1)
# 从上一次停止的位置紧着往下走,在再遇到下一个yield时停止,且可以拿到yield的返回值
r2 = g_obj.__next__()
print(r2)
​
# 生成器可以被for循环迭代
for v in g_obj:
    print(v)
    
# 往生成器中传值的方式:send
def func():
    rev1 = yield 1000
    print(rev1)  # 信息1
    yield 2000
​
obj = func()
# 走到第一个yield得到其返回值 1000
r1 = obj.__next__()
print(r1)
# 给停止的yield发送信息,并调用__next__()去向下一个yield并得到其返回值
r2 = obj.send('信息1')
print(r2)

枚举对象

# 通过for迭代器 循环遍历 可迭代对象,需要知道迭代的索引
for i, v in enumerate('abc'): # 生成迭代器对象:[(0, 'a'),(1, 'b'), (2, 'c')]
    print(i, v)
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄