返回顶部
首页 > 资讯 > 后端开发 > Python >Python中Generators教程的实现
  • 500
分享到

Python中Generators教程的实现

PythonGenerators 2023-02-14 15:02:35 500人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录怎样创建一个python generator?generator函数和普通函数的区别有循环的Python generatorpython generator 表达式python里

要想创建一个iterator,必须实现一个有__iter__()和__next__()方法的类,类要能够跟踪内部状态并且在没有元素返回的时候引发StopIteration异常.

这个过程很繁琐而且违反直觉.Generator能够解决这个问题.

python generator是一个简单的创建iterator的途径.前面讲的那些繁琐的步骤都可以被generator自动完成.

简单来说,generator是一个能够返回迭代器对象的函数.

怎样创建一个python generator?

就像创建一个函数一样简单,只不过不使用return 声明,而是使用yield声明.

如果一个函数至少包含一个yield声明(当然它也可以包含其他yield或return),那么它就是一个generator. 

yield和return都会让函数返回一些东西,区别在于,return声明彻底结束一个函数,而yield声明是暂停函数,保存它的所有状态,并且后续被调用后会继续执行.

generator函数和普通函数的区别

  • generator函数包含一个以上的yield声明
  • generator函数被调用的时候,会返回一个iterator对象,但是函数并不会立即开始执行
  • __iter__()和__next__()方法被自动实现,所以可以使用next()函数对返回的此iterator对象进行迭代
  • 一旦一个generator 执行到yield语句,generator函数暂停,程序控制流被转移到调用方
  • 在对generator的连续调用之间,generator的本地变量和状态会被保存
  • 最终,generator函数终止,再调用generator会引发StopIteration异常

下面这个例子说明上述全部要点,我们有一个名为my_gen()的函数,它带有一些yield声明.

# A simple generator function  
def my_gen():  
    n = 1  
    print('This is printed first')  
    # Generator function contains yield statements  
    yield n  
  
    n += 1  
    print('This is printed second')  
    yield n  
  
    n += 1  
    print('This is printed at last')  
    yield n  

有趣的是,在这个例子里变量n在每次调用之间都被记住了。和一般函数不同的是,在函数yield之后本地变量没有被销毁,而且,generator对象只能被这样迭代一次。

要想重复上面的过程,需要类似 a = my_gen() 这样创建另一个generator对象,并对其使用next方法迭代。

注意

:我们可以对generator对象直接使用for循环。

这是因为一个for循环接收一个iterator对象,且使用next()函数迭代它,当遇到StopIteration异常的时候自动停止。

# A simple generator function  
def my_gen():  
    n = 1  
    print('This is printed first')  
    # Generator function contains yield statements  
    yield n  
  
    n += 1  
    print('This is printed second')  
    yield n  
  
    n += 1  
    print('This is printed at last')  
    yield n  
  
# Using for loop  
  
# Output:   
# This is printed first  
# 1  
# This is printed second  
# 2  
# This is printed at last  
# 3  
  
for item in my_gen():  
    print(item) 

有循环的python generator

上面的例子没有实际的应用意义,我们只是为了探究背后原理。

通常来说,generator都是和循环结合实现的,且这个循环带有一个终止条件。

我们来看一个reverse一个字符串的例子

def rev_str(my_str):  
    length = len(my_str)  
    for i in range(length - 1,-1,-1):  
        yield my_str[i]  
  
# For loop to reverse the string  
# Output:  
# o  
# l  
# l  
# e  
# h  
for char in rev_str("hello"):  
     print(char)  

我们在for循环里面使用range()函数来获取反向顺序的index。

generator除了可以应用于string,还可以应用于其它类型的iterator,例如list,tuple等。

python generator 表达式

使用generator表达式可以很容易地创建简单的generator。

就像lambda函数可以创建匿名函数一样,generator函数创建一个匿名generator函数。

generator表达式的语法类似于python的list comprehension,只是方括号被替换为了圆括号而已。

list comprehension和generator表达式的主要区别在于,前者产生全部的list,后者每次仅产生一项。

它们有些懒惰,仅在接到请求的时候才会产生输出。因此,generator表达式比list comprehension更加节省内存。

# Initialize the list  
my_list = [1, 3, 6, 10]  
  
# square each term using list comprehension  
# Output: [1, 9, 36, 100]  
[x**2 for x in my_list]  
  
# same thing can be done using generator expression  
# Output: <generator object <genexpr> at 0x0000000002EBDAF8>  
(x**2 for x in my_list)  

上面的例子中,generator表达式没有立即产生需要的结果,而是在需要产生item的时候返回一个generator对象。

# Intialize the list  
my_list = [1, 3, 6, 10]  
  
a = (x**2 for x in my_list)  
# Output: 1  
print(next(a))  
  
# Output: 9  
print(next(a))  
  
# Output: 36  
print(next(a))  
  
# Output: 100  
print(next(a))  
  
# Output: StopIteration  
next(a)  

generator表达式可以在函数内部使用。当这样使用的时候,圆括号可以丢弃。

python里为什么要使用generator?

1.容易实现

相对于iterator类来说,generator的实现清晰、简洁。下面是用iterator实现一个2的指数函数

class PowTwo:  
    def __init__(self, max = 0):  
        self.max = max  
  
    def __iter__(self):  
        self.n = 0  
        return self  
  
    def __next__(self):  
        if self.n > self.max:  
            raise StopIteration  
  
        result = 2 ** self.n  
        self.n += 1  
        return result  

generator这样实现

def PowTwoGen(max = 0):  
    n = 0  
    while n < max:  
        yield 2 ** n  
        n += 1  

因为generator自动跟踪实现细节,因此更加清晰、简洁。

2.节省内存

一个函数返回一个序列(sequence)的时候,会在内存里面把这个序列构建好再返回。如果这个序列包含很多数据的话,就过犹不及了。

而如果序列是以generator方式实现的,就是内存友好的,因为他每次只产生一个item。

3.代表无限的stream

generator是一个很棒的表示无限数据流的工具。无限数据流不能被保存在内存里面,并且因为generator每次产生一个item,它就可以表示无限数据流。

下面的代码可以产生所有的奇数

def all_even():  
    n = 0  
    while True:  
        yield n  
        n += 2  

4.generator流水线(pipeline)

generator可以对一系列操作执行流水线操作。

假设我们有一个快餐连店的日志。日志的第四列是每小时售出的披萨数量,我们想对近5年的这一数据进行求和。

假设所有数据都是字符,不可用的数据都以"N/A"表示,使用generator可以这样实现

with open('sells.log') as file:  
    pizza_col = (line[3] for line in file)  
    per_hour = (int(x) for x in pizza_col if x != 'N/A')  
    print("Total pizzas sold = ",sum(per_hour))  

这个流水线既高效又易读,并且看起来很酷!:)

到此这篇关于Python中Generators教程的实现的文章就介绍到这了,更多相关Python Generators内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python中Generators教程的实现

本文链接: https://lsjlt.com/news/196017.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python中Generators教程的实现
    目录怎样创建一个python generator?generator函数和普通函数的区别有循环的python generatorpython generator 表达式python里...
    99+
    2023-02-14
    Python Generators
  • python淘宝爬虫的实现方法教程
    这篇文章主要介绍“python淘宝爬虫的实现方法教程”,在日常操作中,相信很多人在python淘宝爬虫的实现方法教程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python淘宝爬虫的实现方法教程”的疑惑有所...
    99+
    2023-06-25
  • Python实现单项链表的最全教程
    目录单向链表节点实现单链表的操作单链表的实现单链表 判断链表是否为空(is_empty)单链表 链表长度(length)单链表 遍历整个链表(travel)单链表 链表尾部添加元素,...
    99+
    2023-01-07
    Python实现单项链表 Python单项链表
  • Java中实现线程间通信的实例教程
    目录前言1. 如何让两个线程依次执行?2. 如何让两个线程按照指定的方式有序相交?3. 线程 D 在A、B、C都同步执行完毕后执行4. 三个运动员分开准备同时开跑5. 子线程将结果返...
    99+
    2024-04-02
  • python 教程实现 turtle海龟绘图
    目录一、安装二、画布三、画笔四、绘图命令五、画笔控制命令六、全局控制命令七、绘制方形螺旋八、绘制彩色螺旋九、绘制太阳花十、绘制小蟒蛇十一、绘制五角星十二、绘制小猪佩奇一、安装 写出许...
    99+
    2024-04-02
  • 如何在Python中实现重定向?教程来了!
    在Python编程中,重定向是一项非常常见的技术。它允许将标准输出流指向不同的位置,例如文件或字符串。这对于调试和记录程序输出非常有用。在本文中,我们将探讨如何在Python中实现重定向,包括如何重定向标准输出流和标准错误流。 重定向标准...
    99+
    2023-08-23
    重定向 教程 api
  • Python培训教程:基于Python的ModbusTCP客户端实现
    Python培训教程:基于Python的ModbusTCP客户端实现Modbus协议是由Modicon公司(现在的施耐德电气Schneider Electric)推出,主要建立在物理串口、以太网TCP/IP层之上,目前已经成为工业领域通信协...
    99+
    2023-06-02
  • Python的Django框架中消息通知的计数器实现教程
    故事的开始:.count() 假设你有一个Notification Model类,保存的主要是所有的站内通知: class Notification(models.Model): """一个简化过的...
    99+
    2022-06-04
    计数器 框架 消息
  • MongoDB中实现多表联查的实例教程
    前些天遇到一个需求,不复杂,用 SQL 表现的话,大约如此: SELECT * FROM db1 LEFT JOIN DB2 ON db1.a = db2.b WHERE db1.userId='$me'...
    99+
    2024-04-02
  • python项目中requirements.txt的用法实例教程
    记录一下2021.12.11搞环境时遇到了一堆问题师兄跟我说的可以用requirements这个去装环境,不用一个一个装 网上查了一下这个requirements.txt,发现pyt...
    99+
    2024-04-02
  • Python实现农历转换教程详解
    目录前言详细使用方法阳历与农历日期的相互转换闰月其他实战:计算节日距离天数前言 最近处理工作任务的时候遇到了转换农历的问题。一开始我打算搜索在线处理的网站或者转换的接口,结果找到了一...
    99+
    2024-04-02
  • Python Django教程之实现新闻应用程序
    Django是一个用Python编写的高级框架,它允许我们创建服务器端Web应用程序。在本文中,我们将了解如何使用Django创建新闻应用程序。 我们将使用新闻 API 并从 API...
    99+
    2024-04-02
  • Python实现命令行通讯录实例教程
    1、实现目标 编写一个命令行通讯录程序,可以添加、查询、删除通讯录好友及电话 2、实现方法 创建一个类来表示一个人的信息。使用字典存储每个人的对象,名字作为键。 使用pickle模块永久地把这些对象存储...
    99+
    2022-06-04
    命令行 实例教程 通讯录
  • 利用python实现简单的情感分析实例教程
    目录1 数据导入及预处理1.1 数据导入1.2 数据描述1.3 数据预处理2 情感分析2.1 情感分2.2 情感分直方图2.3 词云图2.4 关键词提取3 积极评论与消极评论3.1 ...
    99+
    2024-04-02
  • Python实现人脸识别的详细图文教程
    目录叨叨几句准备工作代码流程总结叨叨几句 哈喽兄弟们,今天实现一下人脸识别。 先问大家一个问题 什么是百度Aip模块? 百度AI平台提供了很多的API接口供开发者快速的调用运用在项目...
    99+
    2024-04-02
  • CSS中实现垂直和水平居中的教程
    本篇内容介绍了“CSS中实现垂直和水平居中的教程”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!CSS Co...
    99+
    2024-04-02
  • Python实现SMTP发送邮件详细教程
    简介 Python发送邮件的教程本人在网站搜索的时候搜索出来了一大堆,但是都是说了一大堆原理然后就推出了实现代码,我测试用给出的代码进行发送邮件时都不成功,后面找了很久才找到原因,这都是没有一个详细的环境调...
    99+
    2022-06-04
    发送邮件 教程 详细
  • python密码学文件解密实现教程
    目录代码输出在本章中,我们将讨论使用Python解密加密文件.请注意,对于解密过程,我们将遵循相同的过程,但不是指定输出路径,而是关注输入路径或加密的必要文件. 代码 以下是使用Py...
    99+
    2024-04-02
  • python密码学实现文件加密教程
    目录代码输出说明在Python中,可以在传输到通信通道之前加密和解密文件.为此,您必须使用插件 PyCrypto .您可以使用下面给出的命令安装此插件. pip ...
    99+
    2024-04-02
  • python twisted中文教程
    先收藏,哇哈哈 python twisted教程 一,异步编程 http://cc.ecjtu.net/posts/python-twisted python twisted教程 二:缓慢的诗 http://cc.ecjtu.net/po...
    99+
    2023-01-31
    中文 教程 python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作