python 可迭代,迭代器,生成器,装饰器

news2024/11/26 12:32:55

1. 可迭代(Iterable)

可迭代 是指一个对象可以返回一个迭代器的对象。也就是说,它实现了 __iter__() 方法或 __getitem__() 方法。常见的可迭代对象有列表、元组、字符串、字典和集合。

from collections.abc import Iterable

i = 100
s = "hello"
l = [1, 2, 3]
t = (1, 2, 3)
d = {"name": "qiku"}
set0 = {1, 2, 3}

print(
    isinstance(i, Iterable),  # False, 整数不可迭代
    isinstance(s, Iterable),  # True, 字符串可迭代
    isinstance(l, Iterable),  # True, 列表可迭代
    isinstance(t, Iterable),  # True, 元组可迭代
    isinstance(d, Iterable),  # True, 字典可迭代(迭代的是键)
    isinstance(set0, Iterable) # True, 集合可迭代
)

2. 迭代器(Iterator)

迭代器 是一个对象,它实现了 __iter__()__next__() 方法(在 Python 3 中,__next__() 方法被称为 __next__())。迭代器可以用于遍历序列中的元素,每次调用 __next__() 方法时,它返回序列中的下一个元素。迭代器在遍历完所有元素后会抛出 StopIteration 异常。

from collections.abc import Iterable, Iterator  # 从 collections.abc 模块导入 Iterable 和 Iterator

class MyDatas:
    def __init__(self, n):
        # 初始化数据列表,从 1 到 n
        self.datas = [i for i in range(1, n + 1)]
        self.current_index = 0  # 当前索引,初始化为 0

    def __iter__(self):
        # 返回自身,因为它既是可迭代对象也是迭代器
        return self

    def __next__(self):
        # 如果当前索引超出数据列表的长度,抛出 StopIteration 异常,表示迭代结束
        if self.current_index >= len(self.datas):
            raise StopIteration
        else:
            # 返回当前索引的数据,并将当前索引加 1
            current = self.datas[self.current_index]
            self.current_index += 1
            return current

md = MyDatas(5)  # 创建一个包含 1 到 5 的 MyDatas 实例

# 打印 md 是否是 Iterable 和 Iterator
print(isinstance(md, Iterable), isinstance(md, Iterator))

# 遍历 MyDatas 实例中的所有数据
for d in md:
    print(d)

3. 生成器(Generator)

生成器 是一种特殊类型的迭代器,使用函数和 yield 关键字来创建。生成器函数可以像普通函数一样定义,但它们使用 yield 来返回值,而不是 return。每次调用生成器的 __next__() 方法时,它会从上次 yield 语句处继续执行,直到遇到下一个 yield 语句或函数结束。

# 定义一个列表 l0,并打印其内存大小
l0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print(l0.__sizeof__())  # 打印 l0 列表在内存中占用的字节数
print(l0[15])  # 打印列表中索引为 15 的元素

# 定义一个生成器表达式 t0,并打印其内存大小
t0 = (i for i in range(1, 1000000000))
print(t0.__sizeof__())  # 打印生成器 t0 在内存中占用的字节数
print(isinstance(t0, Iterable), isinstance(t0, Iterator), isinstance(t0, Generator))  
# 打印 t0 是否是 Iterable、Iterator 和 Generator 类型
print(next(t0), next(t0))  # 打印生成器 t0 的前两个值

# 定义一个生成器函数 my_datas
def my_datas():
    yield 1
    yield 2
    yield 3
    yield 10
    yield 20
    yield 30
    return 100  # 生成器结束时返回的值

r = my_datas()  # 创建生成器对象 r

print(type(r))  # 打印生成器对象 r 的类型

# 使用 while 循环遍历生成器 r 的所有值
while True:
    try:
        print(next(r))  # 打印生成器 r 的下一个值
    except StopIteration as e:  # 捕捉 StopIteration 异常,表示生成器已结束
        print("取完了", e)  # 打印生成器结束时返回的值
        break  # 退出循环

生成器在内存中占用的字节数通常是固定的,比如在上述例子中是 184 字节。即使列表的元素数量增加,生成器的内存占用也不会显著增加。相比之下,当列表中的元素数量增加时,其内存占用量会显著增长。这是因为列表需要为每个元素分配额外的内存来存储数据。而生成器只在需要时生成数据,因而在处理大量数据时,生成器通常比列表更加节省内存。

4. 装饰器(Decorator)不改变函数原有实现给函数添加新功能

装饰器 是一种用于修改或扩展函数或方法行为的设计模式。装饰器是一个函数,它接受一个函数作为参数,并返回一个新的函数。它们常用于日志记录、权限检查、缓存等。

import time
import random

# 定义一个装饰器函数 cost_time,用于计算函数执行时间
def cost_time(f):
    # 定义内部函数 calc,计算并打印被装饰函数的执行时间
    def calc():
        start = time.time()  # 记录开始时间
        f()  # 调用被装饰的函数
        print(f"函数{f.__name__}开销:{time.time() - start}")  # 计算并打印执行时间

    return calc  # 返回内部函数 calc

# 生成一个包含 10000 个随机整数的列表 datas
datas = [random.randint(0, 10000) for i in range(10000)]
# 创建 datas 的副本 datas2
datas2 = datas.copy()

# 使用 cost_time 装饰器装饰 my_sort1 函数
@cost_time
def my_sort1():
    datas.sort(reverse=True)  # 对列表 datas 进行降序排序
    print(datas)  # 打印排序后的列表

# 使用 cost_time 装饰器装饰 my_sort2 函数
@cost_time
def my_sort2():
    datas3 = sorted(datas2, reverse=True)  # 对列表 datas2 进行降序排序,并生成新列表 datas3
    print(datas3)  # 打印排序后的新列表

# 调用装饰后的 my_sort1 函数,计算其执行时间并打印排序结果
my_sort1()

# 调用装饰后的 my_sort2 函数,计算其执行时间并打印排序结果
my_sort2()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2061054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

墙裂推荐!云上机密计算,阿里云上体验了一下海光内存加密和远程认证

🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 机密计算目录 前言1、构…

哈希原理实现

本节主要看源代码实现 哈希特点 哈希(Hashing)是一种将数据映射到固定大小的表中以实现快速查找的数据结构和算法方法。哈希的主要特点包括: 1. 高效的查找、插入和删除 时间复杂度:哈希表通常提供近乎常数时间的查找、插入和…

app安全评估报告的常见留存措施(内附独家资料)

对用户账号、操作时间、操作类型、网络源地址和目标地址、网络源端口、客户端硬件特征等日志信息以及用户发布信息记录的留存措施 1**. 用户账号信息**:我们将用户账号信息安全存储,只有授权的人员能够访问。这些信息包括用户名、电子邮件地址等&#xf…

【C++ 面试 - 面向对象】每日 3 题(六)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…

VAuditDemo审计之二次注入漏洞

目录 VAuditDemo二次注入漏洞 搜索危险函数,用户可控点 regCheck.php messageSub.php message.php 漏洞调用链 漏洞错误利用过程 注册用户 xxxx, 发表payload留言 漏洞正确利用过程 注册用户 wwww\ 退出用户 wwww\\ 使用 wwww\ 登录 发表留言 替换dat…

《javaEE篇》--定时器

定时器概念 当我们不需要某个线程立刻执行,而是在指定时间点或指定时间段之后执行,假如我们要定期清理数据库里的一些信息时,如果每次都手动清理的话就太麻烦,所以就可以使用定时器。定时器就可以比作一个闹钟,可以让…

C++ 设计模式(6. 适配器模式)

适配器模式Adapter Pattern是一种结构型设计模式,它可以将一个类的接口转换成客户希望的另一个接口,主要目的是充当两个不同接口之间的桥梁,使得原本接口不兼容的类能够一起工作。基本结构 Target 是目标接口,Adaptee 是需要适配的…

微信小程序实例代码解读

以微信 小程序开发工具给的示例代码为例&#xff1a; 主页代码&#xff1a; index.wxml 这个文件是一个微信小程序页面的 WXML 结构,主要功能是展示一个快速开始教程的步骤和内容。 源代码&#xff1a; <!--index.wxml--> <view class"container">&l…

ZK-Rollups测评

1. 引言 Matter Labs团队和多个高校研究人员一起&#xff0c;发布2024年论文《Analyzing and Benchmarking ZK-Rollups》&#xff0c;开源代码见&#xff1a; https://github.com/StefanosChaliasos/zkrollup-benchmarking&#xff08;Python&#xff09; 其中&#xff1a; …

安装MySQL入门基础指令

一.安装MySQL(以5.7版本为例) 1.一路默认安装&#xff0c;截图供大家参考 修改自己window安装名字即可 2.配置环境变量 C:\Program Files\MySQL\MySQL Server 5.7\bin 写入系统环境变量即可在window窗口使用其服务了 3.登录MySQL服务 进入控制台输入命令 mysql -u root …

运维小技能:基于Windows系统和‌Linux系统,以tomcat为案例,讲解如何新增自启动服务。

文章目录 引言‌I Linux系统‌(以CentOS为例)基础知识:运行级别(run level)基于chkconfig 工具,设置服务启动类型。基于systemctl 新增系统服务II 基于Windows系统设置服务自启动的常规操作安装多个tomcat服务,并设置自启动。III 扩展制定定时任务优化停止Tomcat服务命令引…

ESP32Cam人工智能教学20

ESP32Cam人工智能教学20 ESP32Cam专用APP 这次我们专门为ESP32Cam量身定制一个手机APP。手机APP是客户端&#xff0c;利用Socket连接ESP32Cam&#xff0c;ESP32Cam成了服务器&#xff0c;实现Socket全双工的数据传输模式&#xff0c;还可以一边显示摄像头图像&#xff0c;一边…

【Canvas与诗词】北岛诗《献给遇罗克》节选(以太阳的名义...)

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>以太阳的名义</title><style type"text/css">…

基类没有虚析构,即使派生类使用智能指针也一定会内存泄漏

实验 定义一个基类和一个派生类 class Base { public:virtual ~Base() default; };class Derive :public Base { public:std::shared_ptr<int> sp{new int{0},[](int *p){delete p;std::cout << "删除器" << endl;},}; };main 函数执行如下代码…

作业08.21

服务器&#xff1a; #include <myhead.h>#define SER_PORT 6666 #define SER_IP "127.0.0.1"int find_client(int *client_arr, int len, int client) {for(int i0; i<len; i){if(client_arr[i] client){return i;}}return -1; }void remove_client(int *…

Mac 使用vscode 创建vue项目后修改文件提示:权限不足,以超级用户身份重试

项目场景&#xff1a; Mac 安装了全局 vue-cli 插件后&#xff0c;使用webpack 创建vue项目&#xff0c;打开项目&#xff0c;选择信任所有文件夹&#xff0c;然后正常编写代码&#xff0c;并对项目中的文件进行修改&#xff0c;点击保存的时候提示&#xff1a;保存“webpack.…

Vue3+Ts封装类似el-dialog的对话框组件

提供11个字段对dialog组件进行控制&#xff1a; modelValue: 对话框显示隐藏控制, width: 控制对话框的宽度, height&#xff1a;控制对话框的高度, top: 控制对话框个距离顶部的距离, title: 控制对话框的标题, appendToBody: 是否将对话框添加至body, closeOnClickModa…

GX Works2的使用方法

目录&#xff1a; 1、概述 2、硬件连接 3、录入与修改程序 1&#xff09;进入编辑按F2或点击“写入模式”图标 2&#xff09;修改部分元件 3&#xff09;注释 4&#xff09;改变显示触点数 4、软仿真与在线仿真 1&#xff09;软仿真 2&#xff09;在线仿真 5、P…

Linux源码阅读笔记-USB设备驱动架构

总线速度及主机控制器 USB系统架构 USB系统主机端提供为4个引脚的A型接口&#xff0c;USB外围设备通过4个引脚的B型接口和主机端连接。那4个引脚&#xff08;一条电压线VBUS、一条地线GND、一条正方向传输数据的D和一条反方向传输数据的D-线。&#xff09;USB主机和USB设备收发…