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

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

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解析--->执行功能
原文地址:https://www.cnblogs.com/caodan01/p/14218576.html