• 三元表达式,列表、字典、集合生成式,生成器表达式,函数递归,匿名函数,面向过程编程


    一、三元表达式,列表、字典、集合生成式,生成器表达式

    1、三元表达式

    三元表达式是python为我们提供的一种简化代码的解决方案,优雅的取代双分支if。语法如下

    res = 条件成立时返回的值 if 条件 else 条件不成立时返回的值
    

    针对下述场景

    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    res = max2(1,2)
    

    用三元表达式可以一行解决

    x=1
    y=2
    res = x if x > y else y # 三元表达式
    

    2、列表生成式

    列表生成式是python为我们提供的一种简化代码的解决方案,用来快速生成列表,语法如下

    案例一
    l = []
    for i in range(10):
        l.append(i)
    print(l)
    用列表生成式可以一行解决
    l = [i for i in range(10)]
    
    案例二
    l = []
    for i in range(10):
        if i > 5:
            l.append(i)
    print(l)
    用列表生成式可以一行解决
    l = [i for i in range(10) if i > 5]
    
    案例三
    names = ["lxx",'hxx',"wxx",'lili']   #如果每个人的名字后面加'_sb'
    l = [name + "_sb" for name in names]
    
    案例四
    names = ["egon","lxx_sb","hxx_sb","wxx_sb"]    #取有'_sb'的值
    res = [name for name in names if name.endswith("sb")]
    

    3、字典生成式

    res = {i: i ** 2 for i in range(5)}
    print(res)  #生成字典
    
    items = [('k1',111),('k2',222),('k3',333)]
       print(dict(items))
    或 print({k:v for k,v in items}) #生成字典
    

    4、集合生成式

    res = {i for i in range(5)}
    print(res)
    

    5、生成器表达式

    创建一个生成器对象有两种方式,一种是调用带yield关键字的函数,另一种就是生成器表达式,与列表生成式的语法格式相同,只需要将[]换成(),即:

    res = (i for i in range(3))
    
    如果我们要读取一个大文件的字节数,应该基于生成器表达式的方式完成
    with open('db.txt','rb') as f:
        nums=(len(line) for line in f)
        total_size=sum(nums) # 依次执行next(nums),然后累加到一起得到结果=
    
    with open('a.txt',mode='rt',encoding='utf-8') as f:
        res = f.read()
        print(len(res))
        
        res = 0
        for line in f:
            res += len(line)
            
        res = sum((len(line) for line in f))
        res = sum(len(line) for line in f)
     
        print(res)
    

    二、函数递归

    1、函数递归调用

    是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用,本质就是一个循环的过程

    #1、递归调用应该包含两个明确的阶段:回溯,递推
        回溯就是从外向里一层一层递归调用下去,
            回溯阶段必须要有一个明确地结束条件,每进入下一次递归时,问题的规模都应该有所减少(否则,单纯地重复调用自身是毫无意义的)
         递推就是从里向外一层一层结束递归
    大前提:递归调用一定要在某一层结束
    
    2、示例
    age(5) = age(4) + 10
    age(4) = age(3) + 10
    age(3) = age(2) + 10
    age(2) = age(1) + 10
    age(1) = 18
    
    def age(n):
        if n == 1:
            return 18
        return age(n-1) + 10
    
    res = age(5)
    print(res)
    
    函数递归取值
    nums = [1,[2,[3,[4,[5,[6,[7,]]]]]]]
    def get(l):   
    	for num in l:      
        	if type(num) is list:       
        		get(num)       
       		 else:            
      		  print(num)
    get(nums)
    

    python中的递归效率低且没有尾递归优化

    #python中的递归
    python中的递归效率低,需要在进入下一次递归时保留当前的状态,在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,尾递归优化:http://egon09.blog.51cto.com/9161406/1842475
    但是python又没有尾递归,且对递归层级做了限制
    
    #总结递归的使用:
    1. 必须有一个明确的结束条件
    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
    

    2、二分法

    想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模

    nums = [-3,1,3,7,13,23,37,43,57,63,77,91,103]  #从小到大排列
    find_num = 64
    def find(nums,find_num):
        print(nums)
        if len(nums) == 0:
            print("not exists")
            return
        mid_index = len(nums) // 2
        if find_num > nums[mid_index]:
            # in the right
            find(nums[mid_index+1:],find_num)
        elif find_num < nums[mid_index]:
            # in the left
            find(nums[:mid_index], find_num)
        else:
            print('you got it')
    find(nums,find_num)
    

    三、匿名函数

    概念

    匿名就是没有名字的函数。特点:临时用一次
    def func(x,y,z=1):
        return x+y+z
    
    匿名
    lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
    func=lambda x,y,z=1:x+y+z 
    func(1,2,3)
    #让其有名字就没有意义
    

    有名字的函数与匿名函数的对比

    #有名函数与匿名函数的对比
    有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能
    
    匿名函数:一次性使用,随时随时定义
    
    应用:max,min,sorted,map,reduce,filter
    

    四、面向过程编程

    #1、首先强调:面向过程编程绝对不是用函数编程这么简单,面向过程是一种编程思路、思想,而编程思路是不依赖于具体的语言或语法的。言外之意是即使我们不依赖于函数,也可以基于面向过程的思想编写程序
    
    #2、定义
    面向过程的核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么
    
    基于面向过程设计程序就好比在设计一条流水线,是一种机械式的思维方式
    
    #3、优点:复杂的问题流程化,进而简单化
    
    #4、缺点:可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身
    
    #5、应用:扩展性要求不高的场景,典型案例如linux内核,git,httpd
    
    #6、举例
    流水线1:
    用户输入用户名、密码--->用户验证--->欢迎界面
    
    流水线2:
    用户输入sql--->sql解析--->执行功能
    
  • 相关阅读:
    Link assemblies causes app crashes if you have an EditText
    Link causes xamarin Android binding library project to crash
    Linux系统目录结构详解
    Centos Linux系统优化二
    Centos Linux系统优化一
    rm命令详解
    mv命令详解
    cp命令详解
    echo命令详解
    touch命令详解
  • 原文地址:https://www.cnblogs.com/caodan01/p/14218576.html
Copyright © 2020-2023  润新知