"""匿名函数1 什么是匿名函数 def定义的是有名函数:特色是能够经过名字重复调用 def func(): #func=函数的内存地址 pass 匿名函数就是没有名字的函数:特色是只能再定义时使用一次 匿名 lambda x,y,z=1:x+y+z #与函数有相同的做用域,可是匿名意味着引用计数为0,使用一次就释放,除非让其有名字 func=lambda x,y,z=1:x+y+z func(1,2,3) #让其有名字就没有意义2 为什么要用匿名函数 强调: 匿名函数的定义就至关于只产生一个变量的值,而没有绑定任何名字, 因此会在定义完以后就被回收,没法重复使用,只能在定义时使用一次 应用:当某一个功能仅使用一次就没有再重复使用的必要了,就应该定义成匿名函数3 有名字的函数与匿名函数的对比 有名函数:循环使用,保存了名字,经过名字就能够重复引用函数功能 匿名函数:一次性使用,随时随时定义4 如何用匿名函数 lambda x,y:x+y 应用:max,min,sorted,map,reduce,filter"""max,min----------------------------lambda x,y:x+y,是一个内存地址nums=[10,-1,11,9,23]print(max(nums))print(max(salaries.values()))salaries = { 'egon练习': 3000, 'alex': 100000000, 'wupeiqi': 10000, 'yuanhao': 2000}匿名函数key=函数的内存地址: 做用是控制max函数的比较的值def func(x): return salaries[x]print(max(salaries,key=func))1. 将可迭代对象salaries变成迭代器对象iter_obj2. next(iter_obj)获得一我的名,而后将该人名看成参数传给key指定的函数, 而后调用函数将函数的返回值看成比较依据3. 比较大小,取出最大值对应的人名print(max(salaries,key=lambda k:salaries[k]))print(min(salaries,key=lambda k:salaries[k]))比较平方的大小max minnums=[10,-1,11,9,23]def func(x): return x**2res=max(nums,key=func)print(res)sorted----------------------------------sorted排序:建立一个新的变量,不会改变原值。sort时会直接覆盖原值。nums=[10,-1,11,9,23]print(sorted(nums))print(sorted(nums,reverse=True))nums.sort()print(nums)nums.sort(reverse=True)print(nums)salaries={ 'egon练习':3000, 'alex':100000000, 'wupeiqi':10000, 'yuanhao':2000}print(sorted(salaries,key=lambda k:salaries[k]))print(sorted(salaries,key=lambda k:salaries[k],reverse=True))map映射,值的数量不变-----------------------names = ['alex', 'wupeiqi', 'yuanhao', 'kevin', 'hu老师']方式一:手动实现new_names=[]for name in names: new_names.append(name+'dsb')print(new_names)方式二:列表生成式new_names = [name + 'dsb' for name in names]print(new_names)方式三:map+匿名函数res = map(lambda x: x + 'dsb', names)print(res)print(list(res))reduce 合并,值的数量减小--------------------方式一:手动实现res=0for i in range(101): res+=iprint(res)方式二:列表生成式print(sum([i for i in range(101)]))方式三:reduce+匿名函数from functools import reduceprint(reduce(lambda x,y:x+y,[i for i in range(101)],100))print(reduce(lambda x,y:x+y,[i for i in range(101)]))print(reduce(lambda x,y:x+y,['h','e','l','l','o'],'----------'))filter筛选---------------------names = ['alex_dsb', 'wxx_sb', 'kevin_sb', 'hu_sb', 'egon练习']方式一:手动实现new_names=[]for name in names: if name.endswith('sb'): new_names.append(name)print(new_names)方式二:列表生成式new_names=[name for name in names if name.endswith('sb')]print(new_names)方式三:filter+匿名函数res=filter(lambda name:name.endswith('sb'),names)print(res)print(list(res))====================================='''递归与二分法1. 什么是函数递归 函数的递归调用是函数嵌套调用的一种特殊形式, 特殊在调用一个函数的过程当中又直接或者间接地调用了该函数自己 递归本质就是一个循环的过程, 可是递归必须知足两个原则: 1. 每进入下一层递归,问题的规模必须有所减小 2. 递归必须有一个明确的结束条件或者说有一个明确的进入下一层递归的条件 而且递归有两个明确的阶段 1. 回溯: 一层一层地递归调用下去 2. 递推: 再某一层结束掉递归,而后一层一层返回 回溯就是从外向里一层一层递归调用下去, 回溯阶段必需要有一个明确地结束条件,每进入下一次递归时, 问题的规模都应该有所减小(不然,单纯地重复调用自身是毫无心义的) 递推就是从里向外一层一层结束递归2, 为什么要用递归 在某些状况下,基于递归来使用重复的过程比while循环更加简单3, 如何用 ''' def f1(): print('from f1') f1() f1() def f2(): print('from f2') f1() def f1(): print('from f1') f2() f1() 递归举例: age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=18 age(n)=age(n-1)+2 # n>1 age(1)=18 # n=1 def age(n): if n == 1: return 18 else: return age(n-1)+2 res=age(5) print(res) list1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, ]]]]]]]]] def func(lines): for line in lines: if type(line)is list: func(line) else: print(line) func(list1) def func(l): for item in l: if type(item) is list: # 将item看成一个新列表传给功能自己 func(item) else: print(item) func(list1)二分法: 二分法是算法的一种,算法是如何高效地解决问题的思路 想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率过低, 用二分法(算法的一种,算法是解决问题的方法)能够极大低缩小问题规模 nums = [1, 13, 15, 23, 27, 31, 33, 57, 73, 81, 93, 94, 97, 101] # 从小到大排列的数字列表 for num in nums: if 58 == num: print('find it') break else: print('not exists') nums = [1, 13, 15, 23, 27, 31, 33, 57, 73, 81, 93, 94, 97, 101] # 从小到大排列的数字列表 find_num = 97 def searh_num(find_num, nums): print(nums) if len(nums) == 0: print('not find!') return mid_num = len(nums) // 2 if find_num>nums[mid_num] : # print('right') nums = nums[mid_num + 1:] # 再次运行功能 searh_num(find_num, nums) elif find_num <nums[mid_num]: # print('left') nums = nums[:mid_num] # 再次运行功能 searh_num(find_num, nums) else: print('find it') searh_num(97, nums) def binary_search(find_num,nums): print(nums) if len(nums) == 0: print('not exists') return # 功能 mid_index = len(nums) // 2 if find_num > nums[mid_index]: # in the right nums=nums[mid_index+1:] # 从新运行功能,传入新列表 binary_search(find_num,nums) elif find_num < nums[mid_index]: # in the left nums=nums[:mid_index] # 从新运行功能,传入新列表 binary_search(find_num,nums) else: print('find it') binary_search(97,nums) binary_search(95,nums)=============================面向过程编程:一、首先强调: 面向过程编程绝对不是用函数编程这么简单, 面向过程是一种编程思路、思想,而编程思路是不依赖于具体的语言或语法的。 言外之意是即便咱们不依赖于函数,也能够基于面向过程的思想编写程序二、定义 面向过程的核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么 基于面向过程设计程序就比如在设计一条流水线,是一种机械式的思惟方式 优势: 复杂的问题流程化,进而简单化 缺点: 可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身三、应用:扩展性要求不高的场景,典型案例如linux内核,git,httpd四、举例 流水线1: 用户输入用户名、密码--->用户验证--->欢迎界面 流水线2: 用户输入sql--->sql解析--->执行功能ps:函数的参数传入,是函数吃进去的食物,而函数return的返回值, 是函数拉出来的结果,面向过程的思路就是,把程序的执行当作一串首尾相连的功能, 该功能能够是函数的形式,而后一个函数吃,拉出的东西给另一个函数吃, 另一个函数吃了再继续拉给下一个函数吃。。。