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

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

1. 可迭代(Iterable)

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

from collections.abc import Iterablei = 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 和 Iteratorclass MyDatas:def __init__(self, n):# 初始化数据列表,从 1 到 nself.datas = [i for i in range(1, n + 1)]self.current_index = 0  # 当前索引,初始化为 0def __iter__(self):# 返回自身,因为它既是可迭代对象也是迭代器return selfdef __next__(self):# 如果当前索引超出数据列表的长度,抛出 StopIteration 异常,表示迭代结束if self.current_index >= len(self.datas):raise StopIterationelse:# 返回当前索引的数据,并将当前索引加 1current = self.datas[self.current_index]self.current_index += 1return currentmd = 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 1yield 2yield 3yield 10yield 20yield 30return 100  # 生成器结束时返回的值r = my_datas()  # 创建生成器对象 rprint(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 进行降序排序,并生成新列表 datas3print(datas3)  # 打印排序后的新列表# 调用装饰后的 my_sort1 函数,计算其执行时间并打印排序结果
my_sort1()# 调用装饰后的 my_sort2 函数,计算其执行时间并打印排序结果
my_sort2()


http://www.mrgr.cn/news/4467.html

相关文章:

  • 解析“吃豆人”小游戏,附赠免费完整代码
  • Linux别名与用户管理体系
  • 紫光同芯推出全球首颗开放式架构安全芯片E450R
  • 字符函数和字符串函数(三)
  • Matplotlib基础入门--数据分析三大件完结
  • 【Nginx】实现 FastCGI
  • 区分有向图和无向图:连通分量
  • [Meachines] [Medium] solidstate Apache JAMES RCE+POP3邮件泄露+定时任务权限提升
  • 在亚马逊云科技上对Stable Diffusion模型提示词、输出图像内容进行安全审核
  • 小程序如何引入自定义组件
  • Linux 开机自动挂载共享文件设置
  • WPS回应“崩了”:提供15天会员补偿,另有新羊毛,你还不来薅?
  • Redis的缓存穿透、击穿、雪崩
  • Android T about screen rotation(二)
  • ArcGIS基础实战丨地图制作、数据制备、矢量空间分析、栅格空间分析、空间插值、DEM数据、
  • SpringBoot如何做自动配置
  • Redis7基础篇(八)
  • QString检查字符串是否包含指定的子字符串的contains函数
  • vue-cron-builder一个相对简易的cron表达式生成插件UI管理javascript
  • 【Python】DrissionPage:一款轻量级的浏览器自动化和网页采集工具