zoukankan      html  css  js  c++  java
  • 11 Python学习之迭代器和生成器

    迭代器和生成器

    迭代器

    可迭代对象:

    当一个对象能够一次返回一个成员,我们称这个对象为可迭代对象,常见的可迭代对象有:

    1. 顺序结构的有:str、list、tupe

    2. 无需结构的有:dict、set

    3. 类的对象拥有 __iter____getitem__ 方法

    迭代器

    当一个可迭代的对象,作为参数传递给内置函数 iter() ,就会返回一个迭代器对象

    迭代器中必须包含__next__ 方法和__iter__ 方法

    判断一个对象是不是迭代器:__next__ 方法和__iter__ 方法在不在dir(对象名)中,dir返回的是一个列表,如果这两个方法在这个列表中,那么该对象就是一个迭代器

    注意:

    如果读取数量超出了迭代器内的成员数量,会报StopIteration 错误;

    例:

    用while循环实现for循环效果:

    li = [1, 2, 3, 4, 5]	# 可迭代对象--列表
    obj = iter(li)          # 可迭代对象传入iter函数,生成迭代器并赋值给obj
    while True:
        try:
            print(next(obj))        # 循环取出迭代器中的值
        except StopIteration:       # 取到最后一个会报错,捕获异常,并退出循环
            break
    

    将可迭代对象转换成迭代器

    语法:

    iter(可迭代对象)

    例1:

    li = list(range(10))
    ret = iter(li)
    print(ret)
    print(ret.__next__())
    print(ret.__next__())
    print(ret.__next__())
    print(next(ret))
    

    运行结果:

    <list_iterator object at 0x7fea39ddf470>
    0
    1
    2
    3

    可迭代对象和迭代器对比

    可迭代对象 迭代器
    占内存空间大(几百万的数据8G内存都能承受) 占内存小
    速度快 速度慢
    可返回 不可返回
    可直观看到数据 数据不可见

    生成器

    在python社区,生成器与迭代器被看成是同一种,生成器的本质就是迭代器。唯一的区别:生成器是我们自己用Python代码构建的数据结构,迭代器是系统提供或转化得来的。

    获取生成器的三种方式:

    1. 生成器函数
    2. 生成器表达式
    3. python内部提供的一些

    yield

    只要在函数中出现了yield,那么他就不是一个函数了,而是一个生成器

    例1:

    # 函数
    def func(a, b):
       return a + b
    
    ret = func(3, 5)
    print(ret)					# 直接返回计算的结果 8
    
    # 生成器
    def func(a, b):
        yield a + b
    
    ret = func(3, 5)
    print(ret)					# 返回的是一个生成器,需要用next获取返回值
    print(next(ret))			# 值是 8
    

    例2:

    生产汽车,按迭代对象的方式,就是一开始就全部生产出来,所用时间和内存都很大

    用生成器,需要多少生产多少,所占内存和使用时间少

    # 迭代对象方式
    def get_func():
        li = []
        for i in range(50001):
            li.append(f"{i}号汽车")
        return li
    
    ret = get_func()
    print(ret)				# 一次创建5万个
    
    # 生成器方式
    def get_func():
        for i in range(50001):
           yield f"{i}号汽车"
    
    ret = get_func()		# 此时,并不会创建,next调用时才创建
    # 生产200辆
    for _ in range(201):	# 创建200个
        print(next(ret))
        
    # 再生产100辆
    for _ in range(100):	# 创建100个
        print(next(ret))
    

    yield from

    yield from返回列表的每一个元素,相当于用了for循环用yield取出

    例1:

    def get_func():
        li = [1, 2, 3, 4, 5]
        yield from li				# 相当于 for i in li: yield i
    
    ret = get_func()
    print(next(ret))
    print(next(ret))
    print(next(ret))
    print("执行了三次")
    print(next(ret))
    

    运行结果:

    1
    2
    3
    执行了三次
    4

    例2:

    def get_func():
        li = [1, 2, 3, 4, 5]
        li2 = ['卫龙', '馒头', '花卷', '包子', '油条']
        yield from li
        yield from li2
    
    ret = get_func()
    for i in range(10):
        print(next(ret), end=' ')
    

    运行结果:

    1 2 3 4 5 卫龙 馒头 花卷 包子 油条

    yield和return的区别

    yield return
    可以存在多个yield,取值时一个next对应一个yield 只能存在一个,遇到return函数就结束了
    需要用迭代器获取返回的结果 直接返回结果

    例1:

    def func(a, b):
       yield a + b
       yield '返回a+b的结果'
       yield '结束'
    
    ret = func(3, 5)
    print(next(ret))
    print(next(ret))
    print(next(ret))
    

    结果是:

    8
    返回a+b的结果
    结束

  • 相关阅读:
    在CMD下用java命令出现“找不到或无法加载主类”问题
    去除后台ckeditor的style="...."的样式
    php图片上传
    html图片预览
    论文阅读
    论文阅读
    论文阅读
    论文阅读
    论文阅读
    论文阅读
  • 原文地址:https://www.cnblogs.com/zcf-blog/p/13427857.html
Copyright © 2011-2022 走看看