生成器表达式

1 生成器表达式定义

生成器表达式并不真正的创建数字列表,而是返回一个生成器对象,此对象在每次计算出一个条目后,把这个条目"产生"(yield)出来。生成器表达式使用了"惰性计算"或称作"延时求值"的机制。生成器表达式可以用来处理大数据文件。

序列过长,并且每次只需要获取一个元素时,应该考虑生成器表达式而不是列表解析。

生成器表达式产生的是一个生成器对象,实质就是迭代器。

2 生成器表达式语法

语法:

  (expression for iter_val in iterable)

  (expression for iter_val in iterable if cond_expr)

例:

g=("egg%s"%i for i in range(100))
print(g)
print(next(g))
print(next(g))

输出结果:

<generator object <genexpr> at 0x0000007E9A403D00>
egg0
egg1

 

可以处理大数据文件:

f=open("a.txt")
l=[]
for line in f:
line = line.strip()
l.append(line)
print(l) f.seek(0)
l1=[line.strip() for line in f]
print(l1) f.seek(0)
g=(line.strip() for line in f)
print(g)
print(next(g))

输出结果:

['wen', 'yan', 'jie']
['wen', 'yan', 'jie']
<generator object <genexpr> at 0x0000000A2B173D00>
wen

4、List函数可以处理迭代器和可迭代对象

List后面可以跟可迭代对象,和for的实质是一样的。 List函数将可迭代对象使用iter方法,变成迭代器,然后使用迭代器的next方法遍历可迭代器的值,并存储为列表类型,在最后报错的时候结束。

文件a.txt的内容是

  wen
yan
jie

编程代码:  

  f=open('a.txt')
g=(line.strip() for line in f)
l=list(g)
print(l)

输出结果:

['wen', 'yan', 'jie']

 

5、sum函数可以处理迭代器和可迭代对象

Sum后面可以跟可迭代对象,和sum的实质是一样的。 Sum函数将可迭代对象使用iter方法,变成迭代器,然后使用迭代器的next方法遍历可迭代器的值,并,在最后报错的时候结束。

g=(i for i in range(10))
print(g)
print(sum(g))
print(sum(range(10)))
print(sum([0,1,2,3,4,5,6,7,8,9]))

输出结果: 

<generator object <genexpr> at 0x0000008ED3FA3D00>
45
45
45

Sum中也可以跟可迭代的对象,跟for,list的工作实质类型

print(sum([1,2,3,4]))

  

 

6、声明式编程 

一种编程方式,将需要很多语句的代码写成声明变量的形式

g=(line.strip() for line in f)

7、 生成器表达式举例

在文件a.txt中的内容:

apple 10 3

tesla 1000000 1

mac 3000 2

lenovo 30000 3

chicken 10 3

1 计算购买总共的花费:

以前的做法:
money_l=[]
with open('a.txt') as f:
for line in f:
goods=line.split()
res=float(goods[-1])*float(goods[-2])
money_l.append(res)
print(money_l)
使用生成器表达式的做法
f=open('a.txt')
g=(float(line.split()[-1])*float(line.split()[-2]) for line in f)
for i in g:
print(i)
f=open('a.txt')
g=(float(line.split()[-1])*float(line.split()[-2]) for line in f)
print(sum(g))
一句话做法:不要这样做,python代码不是要写少,而是要写好,能看懂,且逻辑好
with open('a.txt') as f:
print(sum(float(line.split()[-1])*float(line.split()[-2]) for line in f))

2 将a.txt文件中的每行内容转化为字典类型并且存储到列表

以前做法:

res=[]
with open('a.txt') as f:
for line in f:
l=line.split()
d={}
d["name"]=l[0]
d["price"]=l[1]
d["count"]=l[2]
res.append(d)
print(res)

输出结果:

[{'price': '10', 'name': 'apple', 'count': '3'}, {'price': '1000000', 'name': 'tesla', 'count': '1'}, {'price': '3000', 'name': 'mac', 'count': '2'}, 
{'price': '30000', 'name': 'lenovo', 'count': '3'}, {'price': '10', 'name': 'chicken', 'count': '3'}]

生成器表达式做法

有报错的:

with open('a.txt') as f:
res=(line.split() for line in f)
print(res)
dic_g=({'name':i[0],'price':i[1],'count':i[2]} for i in res)
print(dic_g)
print(dic_g)
print(next(dic_g)) #原因在于dic_g生成器迭代需要res生成器迭代,res生成器迭代需要f迭代器迭代,f是打开文件的句柄,一关闭,res生成器和dic_g生成器都不能使用

输出结果:

<generator object <genexpr> at 0x00000044A0DA3D00>
<generator object <genexpr> at 0x00000044A0DA3E08>
<generator object <genexpr> at 0x00000044A0DA3E08>
ValueError: I/O operation on closed file. #报错

  

正确生成器做法:

with open('a.txt') as f:
res=(line.split() for line in f)
print(res)
dic_g=({'name':i[0],'price':i[1],'count':i[2]} for i in res)
print(dic_g)
apple_dic=next(dic_g)
print(apple_dic["count"])

输出结果:

<generator object <genexpr> at 0x00000081D5243D00>
<generator object <genexpr> at 0x00000081D5243E08>
3

  

3 将a.txt文件中的每行内容转化为字典类型并且取出单价大于10000的商品存储到列表,

生成器表达式调用生成器表达式

with open('a.txt') as f:
res=(line.split() for line in f)
print(res)
dic_g=({'name':i[0],'price':i[1],'count':i[2]} for i in res if float(i[1]) >10000)
print(dic_g)
for i in dic_g:
print(i)

输出结果:

<generator object <genexpr> at 0x000000DB4C633D00>
<generator object <genexpr> at 0x000000DB4C633DB0>
{'price': '1000000', 'count': '1', 'name': 'tesla'}
{'price': '30000', 'count': '3', 'name': 'lenovo'}
with open('a.txt') as f:
res=(line.split() for line in f)
print(res)
dic_g=({'name':i[0],'price':i[1],'count':i[2]} for i in res if float(i[1]) >10000)
print(dic_g)
print(list(dic_g))

输出结果:

<generator object <genexpr> at 0x00000099A0953D00>
<generator object <genexpr> at 0x00000099A0953DB0>
[{'price': '1000000', 'name': 'tesla', 'count': '1'}, {'price': '30000', 'name': 'lenovo', 'count': '3'}]

今日作业

(1)有两个列表,分别存放来老男孩报名学习linux和python课程的学生名字

linux=['钢弹','小壁虎','小虎比','alex','wupeiqi','yuanhao']

python=['dragon','钢弹','zhejiangF4','小虎比']

问题一:得出既报名linux又报名python的学生列表

linux=['钢弹', '小壁虎', '小虎比', 'alex', 'wupeiqi', 'yuanhao']
python=['dragon', '钢弹', 'zhejiangF4', '小虎比']
li=[i for i in linux for j in python if i==j]
print(li)
li=(i for i in linux for j in python if i==j)
print(list(li))

问题二:得出只报名linux,而没有报名python的学生列表

li=[ i for i in linux if i not in python]
print(li)
li=(i for i in linux if i not in python)
print(list(li))

问题三:得出只报名python,而没有报名linux的学生列表

li=[i for i in python if i not in linux]
print(li)
li=(i for i in python if i not in linux)
print(list(li))

(2)

shares={

'IBM':36.6,

'lenovo':27.3,

'huawei':40.3,

'oldboy':3.2,

'ocean':20.1

      }

问题一:得出股票价格大于30的股票名字列表

li=( i for i,j in shares.items() if j > 30)
print(list(li))

问题二:求出所有股票的总价格

li=(float(j) for j in shares.values())
print(sum(li))
print(sum(float(j) for j in shares.values()))

  

(3)

l=[10,2,3,4,5,6,7]

得到一个新列表l1,新列表中每个元素是l中对应每个元素值的平方。过滤出l1中大于40的值,然后求和

l = [10, 2, 3, 4, 5, 6, 7]
l1=[i**2 for i in l]
print(l1)
l2=[i for i in l1 if i >40]
print(sum(l2))

python基础——生成器表达式的更多相关文章

  1. python基础-三元表达式/列表推导式/生成器表达式

    1.三元表达式:如果成立返回if前的内容,如果不成立返回else的内容 name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' ...

  2. 第五章:Python基础の生成器、迭代器、序列化和虚拟环境的应用

    本课主题 生成器介紹和操作实战 迭代器介紹和操作实战 序例化和反序例化 Json 和 Pickle 操作实战 字符串格式化的应用 创建虚拟环境实战 本周作业 生成器介紹和操作实战 什么是生成器,生成器 ...

  3. Python:生成器表达式

    转于:http://www.cnblogs.com/liu-shuai/p/6098218.html 博主:刘-帅 简介: 生成器表达式并不真正的创建数字列表,而是返回一个生成器对象,此对象在每次计算 ...

  4. Python菜鸟之路:Python基础-生成器和迭代器、递归

    一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束.迭代器只能往前不会后退. 1. 迭代器优点 对于无法随机访问的数据结构(比如set)而言, ...

  5. python基础-生成器

    生成器 概念:但凡在函数内部定义了一个yield,调用函数时,函数体代码不会执行,会返回一个结果,该结果就是生成器.本质上是迭代器,一个自定义的迭代器. # python内获取迭代器的方式 def i ...

  6. python基础 生成器 迭代器

    列表生成式: a=[1,2,3] print a b=[i*2 for i in range(10)] #i循环10次,每一个i的值乘2就是列表中的值.列表生成式 print b >>[1 ...

  7. Python练习-生成器表达式-筛选与运算

    # 编辑者:闫龙 l = [10, 2, 3, 4, 5, 6, 7] l1 = [int(i)**2 for i in l] # 得到一个新列表l1,新列表中每个元素是l中对应每个元素值的平方 pr ...

  8. Python基础-生成器和迭代器

    生成器都是迭代器,迭代器不一定是生成器 def fansik(max): n, before, after = 0, 0, 1 while n < max: print(before) befo ...

  9. python基础——生成器与迭代器

    生成器 def func(): print("111") yield 1 print("222") yield 3 print("333") ...

随机推荐

  1. 移动端常用的meta标签,媒体查询以及一些样式设置《转载收藏》

    <meta name="screen-orientation" content="portrait"> <meta name="fu ...

  2. springMVC正确使用GET POST PUT和DELETE方法,如何传递参数

    1. 向服务器请求数据:GET 这是标准的http的GET最擅长的, 应该使用GET请求,但是在使用时候我们会需要传递一个或多个参数给服务器, 这些出参数可能是基本数据类型页可能是对象,get方法可以 ...

  3. 微信公众平台开发,图文回复、access_token生成调用、以及微信SDK的实现(2)

    上一节课,我给大家分享了微信API接入以及事件推送的回复,这是微信开发的第二节课,重点给说一说单图文回复,多图文回复,access_token,微信SDK. 公众号消息回复很多种形式,常见的形式有,文 ...

  4. GLES2学习VBO和VAO的使用

    在GLES2中使用VBO和VAO对象,已经简单vs,ps绘制一个三角形. 1. 初始化操作代码,创建VBO.VAO,编译和链接shader program. void DebugApplication ...

  5. Kaggle竞赛 —— 房价预测 (House Prices)

    完整代码见kaggle kernel 或 Github 比赛页面:https://www.kaggle.com/c/house-prices-advanced-regression-technique ...

  6. ReentrantLock 与 AQS 源码分析

    ReentrantLock 与 AQS 源码分析 1. 基本结构    重入锁 ReetrantLock,JDK 1.5新增的类,作用与synchronized关键字相当,但比synchronized ...

  7. Java 自定义实现链表

    自定义实现链表很简单,只需要明白链表是什么样子的数据结构. 下图表示一种单向列表.其中指针first指向队头,last指向队尾,curr指向当前读的数据. 下面是我的实现代码,很简单,明白上述结构后, ...

  8. c/cpp语言链表连接部分详解

    核心代码: ①pTail->next = pNew; ②pNew->next = NULL; ③pTail = pNew; 设结构体名称为 struct ST: 注:方框代表分配的内存空间 ...

  9. webview缓存及跳转时截取url地址、监听页面变化

    缓存及一些设定 我在做一些项目时,h5做的项目手机浏览器能使用,但是在搬到webview时候不能用,这个时候通过查阅资料,原来是webview没有设定好,包括缓存.缓存大小及路径等等 mWebview ...

  10. Mybatis学习日志

    在Mybatis深入学习的一周中,总感觉跟着师傅的视屏讲解什么都能懂,但实际自己操作的时候才发现自己一脸懵逼,不知道从何入手.但还好自己做了点笔记.在此记录一下自己浅度学习Mybatis遇到几个小问题 ...