day13----迭代器、生成器、枚举对象

一、迭代器:

    1. 定义: (从装有多个值的容器中一次取出一个值给外界)
      1. 器:迭代器是个容器,包含多个值
      2. 迭代:循环反馈,从容器中一次取出一个值
      3. 迭代器不同于索引取值,但是也可以从容器对象中从前往后逐个返回内部的值
    2. 优缺点:
      1. 优点:可以不依赖索引完成取值
      2. 缺点:不能计算长度,不能从指定位置取值
    3. 可迭代对象:
      1. 内置有__iter__()方法的对象就是可迭代对象
      2. 对象:是装有地址的变量
      3. 可迭代:该对象装有__iter__()方法
      4. str、list、tuple、dict、set、range()、enumerate()、file、生成器对象等都是可迭代对象
    4. 迭代器对象
      1. 内置有__next__()方法的对象都是迭代器对象,可以通过调用__next__()方法来完成取值,获取规则是从前往后一次只能取一个值
      2. 迭代器对象:enumerate()、file、生成器对象等
      3. 注意:迭代器对象调用iter()方法后返回的额还是迭代器对象本身
# 遍历对象必须是有序容器:
ls1 = 'abdasdj'
ls = [1, 2, 3, 4, 5]
i = 0
while i < len(ls):
    print(ls[i])
    i += 1

st = {1, 2, 3, 4, 5}
dic = {'a': 1, "b": 2, 'c': 3}

# 可迭代对象概念:
# 对象:装有地址的变量
# 可迭代对象: 该对象有 __iter__()方法

[].__iter__()
{}.__iter__()
().__iter__()
{1, }.__iter__()

# 可迭代对象通过调用__iter__()方法得到迭代器对象
# 迭代器对象就可以做到不依赖索引取值(一次从容器中取出一个值)
# 迭代器对象都有__next__()方法,且通过该方法获取容器中的值,获取规则从前往后取一个值


# 可迭代对象
st1 = {1, 2, 7, 4, 5}
iter_obj = st1.__iter__()  # <set_iterator object at 0x0000000001E98C18>
print(iter_obj)
print([1, 2, 3].__iter__())  # <list_iterator object at 0x0000000001E8EB00>

# 迭代器对象:取一个值少一个值,超出数量就报异常
print(iter_obj.__next__())  # 1
print(iter_obj.__next__())  # 2
print(iter_obj.__next__())  # 4
print(iter_obj.__next__())  # 5
print(iter_obj.__next__())  # 7
# print(iter_obj.__next__())  # print(iter_obj.__next__())  #StopIteration  可以通过try 对异常进行捕获并处理

print("____________________________________________")
# 迭代器对象不能求长度(内部的值的个数)

iter_obj = st1.__iter__()
while True:
    
    try:
        ele = iter_obj.__next__()
        print(ele)
    except StopIteration:
        print('取完了')
        break
        
print("=========================================================")
# for 循环迭代器,自带异常处理的while循环,自动获取被迭代的对象的迭代器对象

iter_obj = st1.__iter__()
for ele in iter_obj:
    print(ele)
    
print("++++++++++++++++++++++++++++++++")
for ele in st1: # 自动完成 for ele in st1.__iter__(): 2.自动完成异常处理
    print(ele)
    
print('|||||||||||||||||||||||||||||||||||||||||||||||||||||||')
# 总结:
# 可迭代对象:有__iter__方法的对象,调用该方法返回迭代器对象
# 迭代器对象:有__next__方法的对象,也就是该方法一次从迭代器对象中获取一个值,取一个少一个
# for 循环迭代器:
#   1.自动获取被迭代对象的迭代器对象:
#   2.在内部一次一次调用—__next__()方法取值:
#   3.自动完成异常处理


# 可迭代对象.__iter__()得到的是该对象的迭代器对象
# 迭代器对象.__iter__()得到的就是迭代器对象本身

二、生成器

    1. 定义:一次返回一个值的容器,生成器内部包含yield关键字的函数。在python中使用了yield 关键字的函数被称为生成器(generator)
    2. 注意:生成器在被调用的过程中不会执行函数,而是返回一个生成器对象。与普通函数不同的是,生成器是一个返回迭代器对象的函数,只能用于迭代操作,更简单点理解生成器就是个迭代器,调用一次生成器返回一个迭代器对象。
def g_fn():
    print(11111111111)
    yield '结果1'
    print(22222222222222)
    yield '结果2'
    print(2222444444444444422)
    yield '结果3'
    print(2233333333333332)
    yield '结果4'


g_obj = g_fn()
r1 = g_obj.__next__()  # 在函数内部执行一次,在遇到下一个yield的时候停止,且可以拿到 yield 的返回值
print(r1)

# 从上一次停止的位置接着往下走,在遇到下一个yield的时候停止,且拿到yield的返回值
r2 = g_obj.__next__()
print(r2)
print('____________________________________________')

for i in g_obj:
    print(i)

print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')


# 生成器的应用案例
# 当访问的数据资源过大,可以将数据用生成器处理,一次值获取所有文件内容的一条资源


def my_range(min, max=0, step=1):
    if max == 0:
        min, max = max, min
    tag = min
    count = step
    while True:
        yield tag
        tag += count
        if tag >= max:
            break


range_obj = my_range(5, 10)
for i in range_obj:
    print(i)

# 文件读取就是典型的生成器的应用

三、枚举对象(enumerate)

  enumerate()函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同事列出数据和数据下标,一般用在for 循环当中。

  语法: enumerate(sequence,[start = 0])

  参数:sequence--一个序列,迭代器或其他支持迭代对象

     start--下标起始位置

  返回值:返回enumerate(枚举)对象

# -*- coding: utf-8 -*-
# for 循环普通形式的遍历
i = 0
seq = ['q', 'z', 'k']
for ele in seq:
    print(i, seq[i])
    i += 1

# 0 q
# 1 z
# 2 k

# for 循环加入enumerate()
for i, ele in enumerate(seq, start=0):
    print(i, ele)

# 0 q
# 1 z
# 2 k
for i, v in enumerate('abc'): # 生成迭代器对象:[(0, 'a'),(1, 'b'), (2, 'c')]
    print(i, v)

猜你喜欢

转载自www.cnblogs.com/qianzhengkai/p/10655131.html
今日推荐