• day20-python-二分、面向过程思想、函数式、模块


    昨日内容回顾

    1、叠加多装饰器
        @deco1     => wrapper1
        @deco2     => wrapper2
        @deco3(1)  => wrapper3
        def index():
            pass
    
    2、yield(了解)
        x=yield 返回值
    
        next(g)
        g.send(1)
    
    3、三元表达式
        res=值1 if 条件 else 值2
    
    4、生成式
        l=[表达式 for x in 可迭代对象 if 条件]
    
    
        g=(表达式 for x in 可迭代对象 if 条件)
        next(g)
        sum(表达式 for x in 可迭代对象 if 条件)
        list(表达式 for x in 可迭代对象 if 条件)
    
    
        dic={键:值 for k in 可迭代对象 if 条件}
        set1={元素 for k in 可迭代对象 if 条件}
    
    5、函数的递归调用
        def f1():
            print(1111)
            print(2222)
            f2()
    
    
        def f2():
            print(2222)
            f1()
    
        f1()
    
    
     def f1():
        print(1111)
        print(2222)
        print(3333)
        f1()
    

    今日内容概要

    1、二分法
    2、面向过程编程思想
    3、函数式
        lambda
        map
        filter
        reduce
    
        sorted
        max
        min
    
    4、模块
    

    今日内容详细

    二分法

    算法:是高效解决问题的办法
    算法之二分法
    
    需求:有一个按照从小到大顺序排列的数字列表
    需要从该数字列表中找到我们想要的那个一个数字
    如何做更高效???
    
    
    nums = [-3, 4, 7, 10, 13, 21, 43, 77, 89]
    find_num = 10
    
    nums = [-3, 4, 13, 10, -2, 7, 89]
    nums.sort() # 二分的前提,序列有序,或者有一个明确的分解点
    print(nums)
    

    方案一:整体遍历效率太低

    for num in nums:
        if num == find_num:
            print('find it')
            break
    

    方案二:二分法

    伪代码模板

    def binary_search(find_num, 列表):
        mid_val = 找列表中间的值
        if find_num > mid_val:
            # 接下来的查找应该是在列表的右半部分
            列表 = 列表切片右半部分
            binary_search(find_num, 列表)
        elif find_num < mid_val:
            # 接下来的查找应该是在列表的左半部分
            列表 = 列表切片左半部分
            binary_search(find_num, 列表)
        else:
            print('find it')
    
    

    示范

    nums = [-3, 4, 7, 10, 13, 21, 43, 77, 89]
    find_num = 8
    
    
    def binary_search(find_num, l):
        print(l)
        if len(l) == 0:
            print('找的值不存在')
            return
        mid_index = len(l) // 2
    
        if find_num > l[mid_index]:
            # 接下来的查找应该是在列表的右半部分
            l = l[mid_index+1:]
            binary_search(find_num, l)
        elif find_num < l[mid_index]:
            # 接下来的查找应该是在列表的左半部分
            l = l[:mid_index]
            binary_search(find_num, l)
        else:
            print('find it')
    
    binary_search(find_num, nums)
    

    面向过程编程思想

    编程思想/范式
    
    面向过程的编程思想:
         核心是"过程"二字,过程即流程,指的是做事的步骤:先什么、再什么、后干什么
         基于该思想编写程序就好比在设计一条流水线
    
    优点:复杂的问题流程化、进而简单化
    缺点:扩展性非常差
    
    面向过程的编程思想应用场景解析:
    1、不是所有的软件都需要频繁更迭:比如编写脚本
    2、即便是一个软件需要频繁更迭,也不并不代表这个软件所有的组成部分都需要一起更迭
    

    函数式

    1、def用于定义有名函数

    func = 函数的内存地址
    def func(x, y):
        return x+y
    
    print(func)
    

    2、lamdab用于定义匿名函数

    print(lambda x, y: x+y)
    

    3、调用匿名函数

    res = (lambda x, y: x+y)(1, 2)
    print(res)
    

    4、匿名函数作用

    用于临时调用一次的场景:更多的是将匿名与其他函数配合使用

    5、匿名函数的示范

    from functools import reduce
    
    salaries = {
        'siry': 3000,
        'tom': 7000,
        'lili': 10000,
        'jack': 2000
    }
    
    max的应用
    res = max(salaries)
    print(res)
    
    def func(k):
        return salaries[k]
    
    res = max(salaries, key=func)  # 返回值=func('siry')
    print(res)
    
    res = max(salaries, key=lambda k: salaries[k])
    print(res)
    
    min的应用
    res = min(salaries, key=lambda k: salaries[k])
    print(res)
    
    sorted排序

    res = sorted(salaries, key=lambda k: salaries[k], reverse=True)
    print(res)

    map的应用(了解)

    下面两个返回的都是生成器

    l = ['alex', 'lxx', 'wxx', '薛贤妻']
    new_l = (name+'_dsb' for name in l)
    print(new_l)
    
    res = map(lambda name: name+'_dsb', l)
    print(res)  # 生成器
    
    filter的应用(了解)
    l = ['alex_sb', 'lxx_sb', 'wxx', '薛贤妻']
    res = (name for name in l if name.endswith('sb'))
    print(res)
    
    res = filter(lambda name: name.endswith('sb'), l)
    print(res)
    
    reduce的应用(了解)
    res = reduce(lambda x, y: x+y, [1, 2, 3], 10)  # 16
    print(res)
    
    res = reduce(lambda x, y: x+y, ['a', 'b', 'c'])  # 'a','b'
    print(res)
    

    模块

    什么是模块?

    模块就是一系列功能的集合体, 分为三大类
    I:内置的模块
    II:第三方的模块
    III:自定义的模块
    一个python文件本身就一个模块,文件名m.py,模块名叫m
    

    模块的形式

    模块有四种形式
        1 使用python编写的.py文件
    
        2 已被编译为共享库或DLL的C或C++扩展
    
        3 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)
    
        4 使用C编写并链接到python解释器的内置模块
    

    为何有用模块

    I: 内置与第三的模块拿来就用,无需定义,这种拿来主义,可以极大地提升自己的开发效率
    II: 自定义的模块
    可以将程序的各部分功能提取出来放到一模块中为大家共享使用
    好处是减少了代码冗余,程序组织结构更加清晰
    

    如何用模块

    1、首次导入模块会发生3件事
        1、执行foo.py
        2、产生foo.py的名称空间,将foo.py运行过程中产生的名字都丢到foo的名称空间中
        3、在当前文件中产生的有一个名字foo,该名字指向2中产生的名称空间
    之后的导入,都是直接引用首次导入产生的foo.py名称空间, 不会重复执行代码
    
    
    2、引用:
    	print(foo.x)
    	print(foo.get)
    	print(foo.change)
    
    强调1:模块名.名字,是指名道姓地问某一个模块要名字对应的值,不会与当前名称空间中的名字发生冲突
    	x = 1111111111111
    	print(x)
    	print(foo.x)
    
    强调2:无论是查看还是修改操作的都是模块本身,与调用位置无关
    
    	x = 3333333333
    	# foo.get()
    	
    	foo.change()
    	print(x)
    	
    	print(foo.x)
    	foo.get()
    
    
    可以以逗号为分隔符在一行导入多个模块,不建议在一行同时导入多个模块
    
    导入模块的规范
    	I. python内置模块
    	II. 第三方模块
    	III. 程序员自定义模块
    
    
    5、import 。。。 as 。。。
    
    6、模块是第一类对象
    
    7、自定义模块的命名应该采用纯小写+下划线的风格
    
    8、可以在函数内导入模块
    def func():
        import foo
    

    作业

    1、文件内容如下,标题为:姓名,性别,年纪,薪资
        egon male 18 3000
        alex male 38 30000
        wupeiqi female 28 20000
        yuanhao female 28 10000
    
    要求:
    从文件中取出每一条记录放入列表中,
    列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式
    
    2 根据1得到的列表,取出薪资最高的人的信息
    3 根据1得到的列表,取出最年轻的人的信息
    4、将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写
    
    5、将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后保存剩下的名字长度
    
    6、求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数)
    
    7、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?(需要使用sum函数)
    
    8、思考题
    
    with open('a.txt') as f:
        g=(len(line) for line in f)
    print(sum(g)) #为何报错?
    9、文件shopping.txt内容如下
    
    mac,20000,3
    lenovo,3000,10
    tesla,1000000,10
    chicken,200,1
    求总共花了多少钱?
    
    打印出所有商品的信息,格式为[{'name':'xxx','price':333,'count':3},...]
    
    求单价大于10000的商品信息,格式同上
    
    10、思考:判断下述说法是否正确
        题目1:
        1、应该将程序所有功能都扔到一个模块中,然后通过导入模块的方式引用它们
        2、应该只将程序各部分组件共享的那一部分功能扔到一个模块中,然后通过导入模块的方式引用它们
    
        题目2:
        运行python文件与导入python文件的区别是什么?
        运行的python文件产生的名称空间何时回收,为什么?
        导入的python文件产生的名称空间何时回收,为什么?
    
  • 相关阅读:
    分页存储过程
    C#,单元测试
    telerik reporting报表
    在Linq to sql 和 Entity framework 中使用lambda表达式实现left join
    .NET提供了三种后台输出js的方式:
    转换人民币大小金额
    ASP.Net Post方式获取数据流的一种简单写法
    js数组中两个有相同删除一个
    我的个人博客
    It is the courage
  • 原文地址:https://www.cnblogs.com/zdw20191029/p/14553352.html
Copyright © 2020-2023  润新知