zoukankan      html  css  js  c++  java
  • 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))

     

  • 相关阅读:
    SQLServer中Case的用法
    SqlServer Convert 函数应用
    探讨SQL Server中Case 的不同用法
    SWF文字查询及高亮显示——第二步:实现文字查询高亮显示基本思路篇
    SWF文字查询及高亮显示——第三步:实现文字查询高亮显示及解决MovieClip帧切换时关键字无法高亮显示的问题
    我平时整理的一个生成机器码的类(转载)
    SWFTools (pdf2swf) to properly work with Flex (精彩转载)
    让Flash的swf文件在客户端不缓存(IIS配置)(强烈推荐)
    开始整SWF文字高亮显示——第一步:解析PDFToFlex源文件(修改补充版)
    解决PDFToFlex源程序的小BUG——页面控制的最后两页无法正常切换问题
  • 原文地址:https://www.cnblogs.com/niejinmei/p/6758287.html
Copyright © 2011-2022 走看看