zoukankan      html  css  js  c++  java
  • Python全栈之路Day22

    初次编辑2017年10月28日,星期六

    摘要

    引用:百度

    1. 列表生成式
    2. 生成器表达式
    3. 面向过程编程
    4. 递归

    一. 上节课复习

    1. 可迭代的:对象有__iter__方法的都是可迭代的对象
    2. 迭代器:对象 .iter()得到的结果就是迭代器
    3. 迭代器的特征:
      1. 迭代器.next()取下一个值
      2. 优点:
        1. 提供了一种统一的迭代对象的方式,不依赖于索引
        2. 惰性计算
      3. 缺点:
        1. 无法获取迭代器的长度
        2. 一次性的,只能往后取值,不能往前退,不能像索引那样去取得某个位置的值
    4. 生成器:函数带有yield关键字,那么这个函数的执行结果就是生成器
    5. 生成器的本质就是迭代器
    def func():
        n=0
        while True:
            yield n
            n += 1
    g=func()
    res=next(g)
    for i in g:
        pass
    1. 总结yield功能:
      1. 相当于把__iter__和__next__方法封装到函数内部
      2. 与return相比,return只能返回一次,而yield可以返回多次
      3. 函数暂停以及继续运行的状态是通过yield保存的
    2. yield的表达式形式:
      food= yield
    def eater(name):
        print('%s start to eat '%name)
        while True:
            food=yield
            print('%s eat %s'%(name,food))
    e=eater('zhejiangF4')
    1. e.send与next(e)的区别
      1. 如果函数内yield是表达式形式,那么必须先next(e)
      2. 二者的共同之处都是可以让函数在上次暂停的位置继续运行,不一样的地方在于send在触发下一次代码的执行时,会顺便给yield传一个值
      3. 另 e.send(None) 和next(e) 效果一样

    二. 协程函数初始化装饰器

    1. 简单装饰器
    def foo(func):
        def foo1(*args,**kwargs):
            res = func(*args,**kwargs)
            next(res)
            return res        #此处理解 生成器是一次性的
        return foo1
    
    @foo        #eater = foo(eater) = foo1
    def eater(name):
        print('%s start to eat food '% name)
        food_list = []
        while True:
            food = yield food_list
            print('%s get %s, to start eat '% (name, food))
            food_list.append(food)
        print('Done')
    
    e = eater('钢蛋')        #foo1('钢蛋')
    print(e.send('123'))

    三. send实现爬网页

    from urllib.request import urlopen
    
    def my_next(func):
        def foo(*args,**kwargs):
            res = func(*args,**kwargs)
            next(res)
            return res
        return foo
    
    @my_next
    def get():
        while True:
            url = yield
            res = urlopen(url).read()        #爬网页返回值
            print(res)        #输出爬网页结果
    
    g=get()
    g.send('http://www.baidu.com')
    g.send('http://www.python.org')

    四. 面向过程的程序设计

    1. 面向过程的编程思想:流水线式的编程思想,在程序设计时,需要把整个流程设计出来
      1. 优点:
        1. 体系结构更加清晰
        2. 简化程序的复杂度
      2. 缺点:
        1. 可扩展性极其差,所以说面向过程的应用场景是:不需要经常变化的软件
    2. 实现 #grep -rl 'python' C:egon
    # grep -rl 'python' C:egon
    import os
    
    #装饰器,将生成器next初始化
    def init(func):
        def foo(*args,**kwargs):
            res = func(*args,**kwargs)
            next(res)
            return res
        return foo
    
    @init
    def search(target):
        '查找文件绝对路径'
        while True:
            dir_path = yield        #此yield放在while外还是内有疑问:yield放在while外就会造成死循环,无法进行下次yield
            g = os.walk(dir_path)        #g为迭代器
            for i in g:
                # print(i)
                for j in i[-1]:
                    file_path = '%s\%s'%(i[0],j)
                    target.send(file_path)
    
    @init
    def opener(target):
        '打开文件获取文件句柄'
        while True:
            file_path = yield
            with open(file_path) as f:
                target.send((f,file_path))        #send传递两个文件时,需加括号
    
    @init
    def cat(target):
        '读取文件内容'
        while True:
            f,file_path = yield
            for line in f:        #读取一行文件
                target.send((line,file_path))
    
    @init
    def grep(target,pattern):    #传递两个参数,其中pattern为要过滤的字符串
        '过滤文件一行中是否有python'
        while True:
            line,file_path = yield
            if pattern in line:
                target.send(file_path)        #需传递文件路径
    
    @init
    def printer():
        '打印文件路径'
        while True:
            file_path = yield
            print(file_path)
    
    g=search(opener(cat(grep(printer(),'python'))))
    g.send('C:\egon')

    五. 列表生成式

    1. 普通表达
    egg_list = []
    
    for i in range(100):
        egg_list.append('egg%s'% i)
    print(egg_list)
    1. 列表生成式表达普通
    egg_list = ['egg%s'%i for i in range(100)]
    print(egg_list)
    1. 列表生成式表达if判断
    #列表内只会添加大于50的数字
    egg_list = ['egg%s'%i for i in range(100) if i >50]
    print(egg_list)
    1. 语法
    [expression for item1 in interable if condition1
                        for item2 in interable if condition2
                        …
                        for itemN in interable if conditionN
                        ]

    类似于

    res = []
    for item1 in interable:
        if condition1:
            for item2 in interable:
                if condition2:
                    …
                    for itemN in interable:
                        if conditionN:
                            res.append(expression )
    1. 实现查找文件绝对路径,以列表的形式表达
    import os
    
    g = os.walk('C:\egon')
    l = ['%s\%s'% (i[0],j) for i in g for j in i[-1]]
    print(l)
    #['C:\egon\a.txt - 副本.txt', 'C:\egon\a.txt.txt', 'C:\egon\a\a.txt.txt', 'C:\egon\a\a2.txt.txt', 'C:\egon\b\a.txt.txt', 'C:\egon\b\a1.txt.txt']

    六. 三元表达式

    name = 'alex'
    name = 'egon'
    
    res = 'sb' if name =='alex' else 'shuai'
    print(res)        #输出shuai

    七.生成器表达式

    1. 语法:与列表生成式相似
    (expression for item1 in interable if condition1
                        for item2 in interable if condition2
                        …
                        for itemN in interable if conditionN
                        )
    1. 优点:省内存,一次只产生一个值在内存中
    2. 应用:读取一个大文件的所有内容,并且行处理
    #读取文件,并去掉每一行两头空格
    f = open('a.txt')
    g= (line.strip() for line in f)
    print(next(g))

    注意:因g为可迭代的,因而可以转换成列表list(g)

    八. 声明式编程

    1. 消费总额计算
    #鸡蛋  5  3
    #特斯拉 10000000.2  5
    #上衣  1000    3
    #裤子  2000    3
    #袜子  100
    #读取包含以上信息的文件,并计算总共花费
    
    #第一种传统写法
    total = []
    with open('b.txt','r',encoding='utf-8') as f:
        for line in f:
            goods=line.split()    #split用法及返回值需加强
            # print(goods)
            res = float(goods[1])*float(goods[-1])
            total.append(res)
    print(total)
    print(sum(total))
    
    #第二种声明式编程写法
    f=open('b.txt','r',encoding='utf-8')    #不能用with 否则会IO操作报错
    total=(float(line.split()[1])*float(line.split()[-1]) for line in f)
    
    print(total)
    print(sum(total))
    1. 文件内容以字典形式嵌套在列表中
    #[{'name': '袜子', 'price': '100', 'num': '3'}, {'name': '袜子', 'price': '100', 'num': '3'}, {'name': '袜子', 'price': '100', 'num': '3'}, {'name': '袜子', 'price': '100', 'num': '3'}, {'name': '袜子', 'price': '100', 'num': '3'}]
    # 基本写法
    res = []
    d = {}
    
    with open('b.txt','r',encoding='utf-8') as f:
        for line in f:
            l = line.split()
            d['name'] = l[0]
            d['price'] = l[1]
            d['num'] = l[2]
            res.append(d)
    print(res)
    1. 模拟数据库查询
    with open('b.txt','r',encoding='utf-8') as f:
        res = (line.split() for line in f)
        dic_g = ({'name':line[0],'price':line[1],'num':line[2]} for line in res)
        goods_dic = next(dic_g)
        print(goods_dic['num'])
    1. 关于with open() 报错
    with open('b.txt') as f:
        d = f
    print(d)        #有内存地址,不是很理解
    print(next(d))    #报错

    作业

    今日总结

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

  • 相关阅读:
    MySQL query_cache_type 详解
    MySQL validate_password 插件
    MySQL冷备份的跨操作系统还原
    MySQL5.7新特性笔记
    MySQL参数详解
    保存mysql用户的登录信息到~.my.cnf文件;用于方便登录操作。
    MySQL应用层传输协议分析
    python egg
    MySQL 加锁处理分析
    train_test_split, 关于随机抽样和分层抽样
  • 原文地址:https://www.cnblogs.com/sama/p/7825409.html
Copyright © 2011-2022 走看看