python基础——生成器表达式
生成器表达式
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))