Python中的【yield】关键字:让【函数】变身成为【生成器】

引言

在Python中,yield是一个非常重要的关键字,它允许我们将一个函数变成一个生成器。生成器是一个非常有用的工具,可以按需生成数据,节省内存空间,并且在处理大数据集时特别有效。在本文中,小编将深入探讨yield关键字的工作原理以及如何使用它来创建生成器。小编将提供示例代码,并附上详细的注释来帮助读者更好地理解。

生成器

生成器是一种特殊的迭代器,它最重要的特性是可以根据需要生成数据,而不是一次性生成所有数据。生成器是通过定义一个包含yield关键字的函数来实现的。当生成器函数被调用时,它返回一个生成器对象。通过在需要时调用生成器对象的next()方法,我们可以逐个获取生成器中的数据项。

实现一个生成器

示例代码

import timedef generator_func():strs = ["I", "am", "GaoSiXiaoGe", "."]for c in strs:print("当前生成器【函数】generator_func\t将返回\t{}".format(c))yield c # 可将yield理解为一种特殊的return ---> return了又没有完全return(看完代码后有同感的,可以动动发财的小手点个赞支持一下~)time.sleep(5)print("5秒已过!")# 调用生成器函数, 返回生成器对象generator
generator_obj = generator_func()# 根据需要生成数据 —— 每隔5s生成一个数据
for s in generator_obj: # 每次遍历生成器对象 --> 相当于调用生成器对象的next()方法print("当前生成器【对象】generator_obj\t弹出了\t{}".format(s))

运行结果
在这里插入图片描述

小结

  • 【生成器】可以借助带有yield关键字的函数来实现。
  • 调用生成器【函数】,会返回一个生成器【对象】。
  • 执行生成器函数时,每次遇到yield语句时,生成器函数会【暂停执行】并将数据返回给调用者(生成器对象)。
  • 当需要生成下一个数据时,生成器【函数】会从停止的位置继续执行,直到找到下一个数据项。

生成器在PyTorch中的应用举例

使用生成器实现数据集的按需读取

示例代码

import torch  
from torch.utils.data import Dataset, DataLoader  # 自定义数据集类,继承自Dataset类  
class MyDataset(Dataset):  def __init__(self, data):  self.data = data  def __getitem__(self, index):  # 返回数据项和标签  return self.data[index][0], self.data[index][1]  def __len__(self):  # 返回数据集大小  return len(self.data)  # 定义数据集加载器类,继承自DataLoader类
class MyDataLoader(DataLoader):  def __init__(self, *args, **kwargs):  super().__init__(*args, **kwargs)  def __iter__(self):  # 生成器函数# 使用生成器实现数据集的按需读取  for data, target in self.dataset:  yield data, target  # 创建数据集和加载器实例  
data = [(torch.randn(5), torch.randn(1)) for _ in range(100)]  
dataset = MyDataset(data)  
dataloader = MyDataLoader(dataset, batch_size=10, shuffle=True) # 生成器对象# 使用生成器对象dataloader迭代数据集  
for data, target in dataloader:  print(data.shape, target.shape)

使用生成器实现自定义的数据增强功能

示例代码

import torch  
from torchvision import transforms  
from torch.utils.data import Dataset, DataLoader  # 自定义数据集类,继承自Dataset类  
class MyDataset(Dataset):  def __init__(self, data, transform=None):  self.data = data  self.transform = transform  # 数据增强函数  def __getitem__(self, index):  # 返回数据项和标签  img, label = self.data[index]  if self.transform:  img = self.transform(img)  # 对图像进行数据增强处理  return img, label  def __len__(self):  # 返回数据集大小  return len(self.data)  # 定义数据增强函数,使用生成器实现随机裁剪功能  
def random_crop(image, crop_size):  h, w = image.shape[-2:]  # 获取图像的高和宽  x = torch.randint(0, w - crop_size + 1, size=(1,))  # 随机生成裁剪起始点的x坐标  y = torch.randint(0, h - crop_size + 1, size=(1,))  # 随机生成裁剪起始点的y坐标  image = image[:, y:y+crop_size, x:x+crop_size]  # 对图像进行裁剪处理  return image  # 创建数据集和加载器实例,并应用数据增强功能  
data = [(torch.randn(3, 64, 64), torch.randn(1)) for _ in range(100)]  # 创建包含100个随机生成的图像和标签的数据集  
transform = transforms.Compose([transforms.Lambda(lambda x: random_crop(x, 32))])  # 定义数据增强函数,实现随机裁剪功能,将图像裁剪为32x32大小  
dataset = MyDataset(data, transform=transform)  # 创建数据集实例,并应用数据增强功能  
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)  # 创建加载器实例,设置批次大小为10,并启用随机打乱功能  # 使用生成器迭代数据集,查看增强后的数据效果  
for data, target in dataloader:  print(data.shape, target.shape)  # 打印增强后的数据的形状,分别为(10, 3, 32, 32)和(10, 1)

结束语

  • 亲爱的读者,感谢您花时间阅读我们的博客。我们非常重视您的反馈和意见,因此在这里鼓励您对我们的博客进行评论。
  • 您的建议和看法对我们来说非常重要,这有助于我们更好地了解您的需求,并提供更高质量的内容和服务。
  • 无论您是喜欢我们的博客还是对其有任何疑问或建议,我们都非常期待您的留言。让我们一起互动,共同进步!谢谢您的支持和参与!
  • 我会坚持不懈地创作,并持续优化博文质量,为您提供更好的阅读体验。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

教师们如何一对一私发成绩?

在传统的教育中,老师通常会通过班级群或家长会等方式发布学生的成绩信息。然而,这种公开的方式可能会让一些学生感到尴尬和不安,因为他们可能不愿意让其他人知道他们的成绩情况。为了解决这个问题,今天我就给老师们推荐一款免费的…

JavaEE之多线程编程:1. 基础篇

文章目录 一、关于操作系统一、认识进程 process二、认识线程三、进程和线程的区别(重点!)四、Java的线程和操作系统线程的关系五、第一个多线程编程 一、关于操作系统 【操作系统】 驱动程序: 如:我们知道JDBC的驱动程…

对象与对象数组

对象与对象数组 实验介绍 本章节主要介绍对象数组和对象成员。在实际的开发中,对象数组和对象成员是经常使用的,所以首先需要学习对象数组与对象成员的各种使用方法。 提示:为了方便课程讲解,示例代码使用类内定义的方式实现&a…

【JUC】二十四、线程局部变量ThreadLocal

文章目录 1、ThreadLocal2、常用方法3、案例4、线程池下必须remove掉线程的LocalThread值5、Thread、ThreadLocal、ThreadLocalMap6、Thread、ThreadLocal、ThreadLocalMap的关系 1、ThreadLocal ThreadLocal提供线程局部变量,这些变量与正常的变量不同,…

vm虚拟机固定IP

最近使用vm虚拟机 ,可用了一段时间ip就自动变化,于是去网上看了不少教程,但很多都没用。 1.编辑配置 vim /etc/sysconfig/network-scripts/ifcfg-ens33 修改BOOTPROTO为static加入属性IPADDR,设置你想要设置的ip配置GATEWAY与DNS1 不配置GA…

Leetcode—2962.统计最大元素出现至少 K 次的子数组【中等】

2023每日刷题&#xff08;五十六&#xff09; Leetcode—2962.统计最大元素出现至少 K 次的子数组 滑动窗口算法思想 参考的灵神思路 实现代码 class Solution { public:long long countSubarrays(vector<int>& nums, int k) {int n nums.size();long long ans…

文心一言 VS 讯飞星火 VS chatgpt (154)-- 算法导论12.3 1题

一、用go语言&#xff0c;给出 TREE-INSERT 过程的一个递归版本。 文心一言&#xff0c;代码不能运行&#xff1a; 下面是用 Go 语言实现一个递归版本的 TREE-INSERT 过程的代码&#xff1a; package main import "fmt" type TreeNode struct { Val int Lef…

JUC并发编程03——LockSupport与线程中断

一.线程中断机制 假设从网络下载一个100M的文件&#xff0c;如果网速很慢&#xff0c;用户等得不耐烦&#xff0c;就可能在下载过程中点“取消”&#xff0c;这时&#xff0c;程序就需要中断下载线程的执行。 1.1如何停止中断运行中的线程&#xff1f; 通过一个volatile变量…

Android--Jetpack--Databinding源码解析

慢品人间烟火色&#xff0c;闲观万事岁月长 一&#xff0c;基本使用 关于databinding的基本使用请看之前的文章 Android--Jetpack--Databinding详解-CSDN博客 二&#xff0c;xml布局解析 分析源码呢&#xff0c;主要就是从两方面入手&#xff0c;一个是使用&#xff0c;一个…

D28|买卖股票的最佳时机+跳跃游戏

122.买卖股票的最佳时机 II 初始思路&#xff1a; 这道题解题的时候比较像在找规律&#xff0c;发现只要计算这个过程中的两数之差然后相加即可。 题解复盘&#xff1a; 可以更加清晰的发现如何从题意中获得贪心的思路。 如何贪心&#xff1a;局部最优&#xff1a;收集每天的…

mybatis多表映射-延迟加载,延迟加载的前提条件是:分步查询

1、建库建表 create database mybatis-example; use mybatis-example; create table t_book (bid varchar(20) primary key,bname varchar(20),stuid varchar(20) ); insert into t_book values(b001,Java,s001); insert into t_book values(b002,Python,s002); insert into …

2024美赛备战2--模型建立(*****必看****)

建模 美赛涉及的建模知识范围非常广且深&#xff0c;纵观美赛真题不难发现&#xff0c;很多的模型 都是读研或者读博的时候才会真正深入开始研究&#xff0c;因此&#xff0c;对于做建模的同学来说&#xff0c; 是无法在赛前吃透大量模型的。推荐本科生分两个步骤去有效准备比赛…