当前位置: 首页 > article >正文

生成器和迭代器

迭代器

定义

迭代器是一个实现了选代协议的对象,它可以让我们遍历一个容器中的所有元素,而不需要知道容器的内部结构,迭代器可以被用于遍历列表、元组、字典、集合等容器类型。

工作原理

__iter__():方法返回迭代器对象本身,有__iter__()方法的是一个可迭代对象。
__next__():返回容器中的下一个元素,直到容器中的所有元素都被遍历完毕后,再调用 next()方法就会抛出Stoplteration异常,表示迭代已结束。
__next__()方法的是迭代器

其他方法

# 返回iterator(迭代器)
print([1,2].__iter__())
print(iter([1,2,3]))

iter_l = [1,2,3,4,5]
iter_l = [1,2,3,4,5].__iter__()
# __length_hint__:获取的是迭代器元素的长度
print(iter_l.__length_hint__())
# __setstate__:根据索引指定索引位置
iter_l.__setstate__(3)
print(iter_l.__next__())
print(iter_l.__next__())
print(iter_l.__next__())

输出结果:
在这里插入图片描述
最后因为所有元素元素都被遍历,所以报错

迭代器的创建:

  # 创建一个返回数字的迭代器,初始值为1,逐步递增1,并输出结果
class MyNum:
    def __iter__(self):   # 可迭代对象
        self.num = 1
        return self
    def __next__(self):
        n = self.num
        self.num += 1
        return n
mynum = MyNum()
 # 获取迭代器对象
myiter = iter(mynum)
 # myiter = mynum.__iter__()获取迭代器对象的迭代器
print(next(myiter))
print(next(myiter))
print(next(myiter))

生成器

定义

是Python中一种特殊的迭代器,它是一个能按需生成值的轻量级对象。

yield

yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。
生成器是一个返回迭代器的函数,只能用于迭代操作

创建生成器

'''创建一个生成器'''
 # 第一种方法:元组推导式
gen = (x*x for x in range(4))
List = [x*x for x in range(4)] # 以[]的为列表
print(gen)
print(List)
print()
 # 第二种方法:生成器函数
def gen2():
    for i in range(5):
        yield i   # yield表示暂停程序,可以使用next函数和sent函数唤醒程序
gen_2 = gen2()
print(gen_2)
print(next(gen_2))
print(next(gen_2))
print(gen_2.send(8))

用生成器模拟银行存款机

# 定义一个模拟银行取款机的函数
def bank_account():
    # 最初金额
    balance = 500
    while True:
        # 使用send函数传入amount的值
        amount = (yield balance)
        if amount is not None:
            # 模拟存款,balance增加
            if amount >= 0:
                balance += amount
                print(f"存款后,金额为{balance}")
            # 模拟取款,balance减少
            else:
                # 取款金额大于本金,无法取出
                if balance < -amount:
                    print(f"金额不足,无法取出")
                # 取款金额小于本金,可以取出
                elif balance >= amount:
                    balance += amount
                    print(f"取款后,金额为{balance}")
        else:
            print("没有存取款金额")
 # 创建生成器实例
account = bank_account()
 # 初始化生成器,执行到第一个yield语句
next(account)
 # 使用send方法传入account的值
 # 存入600元
account.send(600)
 # 取出200元
account.send(-200)
 # 再取出1000元
account.send(-1000)

生成器与迭代器的创建区别

1.生成器使用def定义函数创建,只要有yield关键字就是生成器
2.迭代器使用class来创建,需要同时包含__iter__()__next__()两个方法才能使迭代器

闭包

定义

在一个函数的内部定义了另一个函数,外部的函数叫它外函数,内部的函数叫它内函数。

条件

1.在一个外部函数里定义一个内部函数
2.内部函数运用了外部函数的临时变量
3.外部函数的返回值是内部函数的引用

创建闭包

def outer(logo):
    def inner(msg):
        print(f"{logo}-{msg}-{logo}")
    return inner
n1 = outer("吃饭")
n1("睡觉")
n1("打游戏")
 # 输出结果:
 # 吃饭-睡觉-吃饭
 # 吃饭-打游戏-吃饭

用闭包实现银行取款功能

def outer(discount):
    def inner(account):
        nonlocal discount
        if account is not None:
            if account > 0:
                discount+=account
                print(discount)
            else:
                discount+=account
                if discount >= 0:
                    print(discount)
                else:
                    print("金额不足无法取出")
        else:
            print("没有计算金额")
    return inner
n1 = outer(1500)
n1(500)  # 输出:2000
n1(-600)   # 输出:1400
n1(-1500)   # 输出:金额不足无法取出

装饰器

实质上也是一个 闭包函数——函数嵌套。

作用

在不改变原函数的情况下,对已有函数进行额外的功能扩展

条件

装饰器的形成条件(与包的区别):

1.不修改已有函数的源代码
2.不修改已有函数的调用方式
3.给已有函数增加额外的功能

实现装饰器

def decorator(func): # 将函数作为参数,装饰函数
    def inner():
        print("现在睡觉")
        func()
        print("起床了")
    return inner

def sleep():  # 目标函数
    import random
    import time
    print("睡眠中...")
    time.sleep(random.randint(3,8))
fun = decorator(sleep)
fun()

http://www.kler.cn/a/355087.html

相关文章:

  • 专栏二十三:Python读取和分析空间数据的经验杂谈
  • 虚幻引擎结构之ULevel
  • Linux搭建TRELLIS详细流程
  • springBoot Maven 剔除无用的jar引用
  • idea设置控制台日志输出自动换行
  • JavaScript中的Set、Map、WeakSet和WeakMap
  • Mysql 5.7 安装与卸载(非常详细)
  • 【原创】java+springboot+mysql智能农村管理系统设计与实现
  • OpenUAV:首个专为现实无人机视觉语言导航设计的大规模轨迹数据集,由大约 12k 个轨迹组成,涵盖了多种环境和复杂的飞行动态。
  • laravel清除不同缓存
  • 疾病防控|基于springBoot的疾病防控综合系统设计与实现(附项目源码+论文+数据库)
  • 海康相机
  • 通信学习干货:运营商为什么要大力推广FTTR?
  • 2. 继承Mono的单例模式基类
  • 一文搞懂模型倍率怎么计算的,以及模型分组倍率原理!
  • Java | Leetcode Java题解之第480题滑动窗口中位数
  • 决策树C4.5算法详解及实现
  • openEuler-22.03-SP4离线编译安装ZLMediaKit
  • A Survey on 3D Gaussian Splatting 整理
  • XML 和 SimpleXML 简介
  • linux环境下的程序设计与git操作
  • 【MySQL】入门篇—基本数据类型:NULL值的概念
  • 利用mydumper从MySQL迁移数据到OceanBase数据库命令记录
  • PHP学习记录-编辑器推荐和本地环境的安装
  • 锁定云轴科技ZStack主题演讲,10月19日中国云计算基础架构开发者大会见
  • WHAT - Antd 定制主题之预设算法