本篇将介绍python生成器,更多内容请参考:python学习指南

前言

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅访问前面几个元素,那后面绝大多数占用的空间都白白浪费了。

python生成器是用来代替"不一定能够使用全部元素的数组",等到使用某一元素时,才生成该元素,用来节省空间.

生成器创建方式

第一种:

在前面我们介绍python列表生成式,这里我们只需要把列表生成式的[]改成(),就创建了一个generatro

>>>L = [x * x for x in range(10)]
>>>L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>>g = (x*x for x in range(10))
>>>g
<generator object <genexpr> at 0x1022ef630>

创建Lg的区别仅在于最外层的[](),L是一个list,而g是一个generator

上面表达式中我们可以直接列出list(L)的每一个元素,但我们打印g的时候,却打印了g的类型,那么,我们如何打印generator的每一个元素呢?

如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:

>>>next(g)
0
>>>next(g)
1
>>>next(g)
4
>>>next(g)
9
>>>next(g)
16
>>>next(g)
25
>>>next(g)
36
>>>next(g)
49
>>>next(g)
64
>>>next(g)
81
>>>next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,知道计算出最后一个元素,没有更多元素时,抛出StopIteration的错误。

这样不断调用next(g)实在是太变态了,生成器是可迭代对象

>>>from collections import Iterable  #载入模块
>>>isinstance(g, Iterable) #生成器是可迭代对象吗?
True

这样,知道用什么来了吧?

当然是使用强大的for...in迭代来实现

>>>g = (x * x for x in range(10))
>>>for n in g:
print(n)
0
1
4
9
16
25
36
49
64
81

通过for迭代的方式来循环生成器,并不用关心StopIteration的错误。

使用关键字 yield 关键字

generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现

斐波那契数列生成器

def creatNum():
print("---开始执行生成器方法---")
a,b = 0,1
for i in range(0,5):
print("--step1--")
yield b
print("--step2--")
a,b = b,a+b
print("--step3--")
print("--stop--") print("直接调用方法...")
print(creatNum()) #这里用一个标识符来指向生成器(不要把creatNum()当做函数)
func = creatNum() #使用for循环来执行生成器
for i in func:
print(i)
输出结果: (执行完毕不会崩溃) #直接调用方法...
<generator object creatNum at 0x101c30f10>
---开始执行生成器方法---
--step1--
1
--step2--
--step3--
--step1--
1
--step2--
--step3--
--step1--
2
--step2--
--step3--
--step1--
3
--step2--
--step3--
--step1--
5
--step2--
--step3--
--stop--

在执行生成器时,可以使用 生成器.send(param) 方法

send方法不光是执行一步next操作,还会把send里面的参数传到生成器中充当yield表达式的返回值

def test():
i = 0
while i < 5:
temp = yield i
print(temp)
i += 1 t = test() #先使用next执行,看能出来什么结果
t.__next__()
t.__next__()
print(t.__next__()) #使用send执行
t.send("1231231231223123")
print(t.send("hahahahhahaha"))
输出结果: (可见next输出temp为none , 而send 则把值传递进了生成器) None
None
2
1231231231223123
hahahahhahaha
4

参考

  1. python生成器是怎样工作的
  2. Python中的yield关键字
  3. python生成器
  4. 廖雪峰-生成器

Python列表生成器的更多相关文章

  1. python 列表生成器

    python 列表生成器 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 一个循环 在C语言等其他语言中,for循环一般是这样的 ...

  2. 三、python高级特性(切片、迭代、列表生成器、生成器)

    1.python高级特性 1.1切片 list列表 L=['Mli','add','sal','saoo','Lkkl'] L[0:3]  #即为['Mli','add','sal']  从索引0开始 ...

  3. Python 函数 切片 迭代 列表生成器

    函数 编写     定义一个函数要用def语句    def sum(i,n):   ⚠有冒号 返回多值     实际上是返回一个tuple 定义默认参数    默认参数的作用是简化调用   def ...

  4. Python中的列表生成器,迭代器的理解

    首先,思考一个问题,比如,我们想生成0-100的列表,我们怎么做? 当然,可以写成 list1=[1,2,3...,100] 可以看出,这种方法不适合生成长的列表,那么Python中就可以利用已有的列 ...

  5. 洗礼灵魂,修炼python(15)--列表进阶话题—>列表解析/列表生成器

    是的,我是想到什么知识点就说什么,没有固定的主题,我的标题都是在写完博客再给的.本篇博文说说列表进阶话题.其实列表应该是比较熟悉的了,而毫不夸张的说,在实际的开发中,列表也是使用的最多的,以后你会体会 ...

  6. Python列表解析与生成器表达式

    Python列表解析 l = ["egg%s" %i for i in range(100) if i > 50] print(l) l= [1,2,3,4] s = 'he ...

  7. 【Python学习之五】高级特性3(切片、迭代、列表生成器、生成器、迭代器)

    3.列表生成器(List Comprehensions) 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式.举个例子,要生成list ...

  8. Python 的列表生成器

    列表生成器为创建列表提供了一种简洁的方式. 比如说,我们可以这样实现一个平方数列表 squares=[x**2 for x in range(10)] 或者这样迭代一个字符串来生成列表 >> ...

  9. python语法_列表生成器_生成器_迭代器_异常捕获

    列表生成式 a = [x for x in range(10)] print(a) x 可进行操作 a = [x*2 for x in range(10)] print(a) x甚至可以为函数, de ...

随机推荐

  1. 什么是XP

    极限编程(XP)是敏捷过程中最富盛名的一个.下述这些特点使得敏捷过程能够较好地适应商业竞争环境下对小型项目提出的有效资源和有限开发时间的约束. 极限编程的有效实践 极限编程的整体开发过程 极限编程的迭 ...

  2. 对弈的Python学习笔记

    #主要序列类型 str list tuple #列表 list ls=[1,2,3,4]#末尾追加ls.append(5) #添加多个,扩展ls.extend([5,6,7]) #在某个位置插入一个值 ...

  3. Java基础-流程控制语句与运算符

    运算符 算术运算符 ++ -- 在前时先运算后取值:在后时先取值后运算 关系运算符 == !=也可以是引用类型 位运算符 逻辑运算符 赋值运算符 条件运算符 (?:) 布尔表达式 ? 表达式1 : 表 ...

  4. BeanUtils出现Java.lang.NoClassDefFoundError解决

    问题描述: javaWeb项目中导入了BeanUtils的两个包,但是还是出现Java.lang.NoClassDefFoundError: org/apache/commons/beanutils/ ...

  5. freemarker中的null异常处理以及!与??的使用(转)

    原文链接: https://blog.csdn.net/mexican_jacky/article/details/50638062 阅读数:6304 如工程包含: 在user中我们有个角色,那么我们 ...

  6. openstack网络DVR

    一.DVR描述 分布式路由 二.相关的专业术语 术语名称 术语解释 SNAT 在路由器后(POSTROUTING)将内网的ip地址修改为外网网卡的ip地址,也就是绑定浮动IP和外部通信 DNAT 在路 ...

  7. 【Python】requests.post请求注册实例

    #encoding=utf-8 import requests import json import time import random import multiprocessing from mu ...

  8. 2.12 单选框和复选框(radiobox、checkbox)

    2.12 单选框和复选框(radiobox.checkbox) 本篇主要介绍单选框和复选框的操作一.认识单选框和复选框    1.先认清楚单选框和复选框长什么样 2.各位小伙伴看清楚哦,上面的单选框是 ...

  9. JavaScript Dom基础-9-Dom查找方法; 设置DOM元素的样式; innerHTML属性的应用; className属性的应用; DOM元素上添加删除获取属性;

    JavaScript Dom基础 学习目标 1.掌握基本的Dom查找方法 domcument.getElementById() Domcument.getElementBy TagName() 2.掌 ...

  10. Java中的国际化

    一.什么是国际化? 国际化是指应用程序运行时,可根据客户端请求来自的国家/地区.语言的不同而显示不同的界面. 二.Java如何实现国际化? Java程序的国际化思路是将程序中的标签.提示等信息放在资源 ...