"""匿名函數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的返回值, 是函數拉出來的結果,面向過程的思路就是,把程序的執行當作一串首尾相連的功能, 該功能能夠是函數的形式,而後一個函數吃,拉出的東西給另一個函數吃, 另一個函數吃了再繼續拉給下一個函數吃。。。