一、匿名函數 匿名函數主要是為瞭解決一些簡單需求而設計的一種函數,匿名函數的語法為: lambda 形參: 返回值 先來看一個例子: 使用匿名函數需要註意的幾點: 函數的參數可以有多個,多個參數之間⽤逗號隔開 匿名函數不管多複雜. 只能寫⼀⾏, 且邏輯結束後直接返回數據 返回值和正常的函數⼀樣, 可 ...
一、匿名函數
匿名函數主要是為瞭解決一些簡單需求而設計的一種函數,匿名函數的語法為:
lambda 形參: 返回值
先來看一個例子:
# 計算n的n次方
In[2]: lst = lambda n: n ** n # 這裡的lst就是一個匿名函數
In[3]: print(lst(3))
27
使用匿名函數需要註意的幾點:
- 函數的參數可以有多個,多個參數之間⽤逗號隔開
- 匿名函數不管多複雜. 只能寫⼀⾏, 且邏輯結束後直接返回數據
- 返回值和正常的函數⼀樣, 可以是任意數據類型
二、內置函數補充
sorted
sorted是python內置的一個用於排序的函數,它接收三個參數,語法為;
sorted(Iterable, key=None, reverse=False)
- Iterable: 接收一個可迭代對象,sorted內部會去迴圈可迭代對象取出元素
- key: 排序規則(排序函數),sorted將每次從可迭代對象中取出的數據會傳遞給這個排序函數的參數,根據函數運算的結果進行排序
- reverse: 控住是否倒敘,True為倒敘,預設為False正序
# 根據字元串⻓度進⾏排序
In[7]: lst = ["麻花藤", "岡本次郎", "中央情報局", "狐仙"]
In[8]: lst2 = sorted(lst, key=lambda s: len(s))
In[9]: print(lst2)
['狐仙', '麻花藤', '岡本次郎', '中央情報局']
sorted如果不傳作排序用的函數,那麼它預設是按照在字元編碼中的順序來排的:
In[10]: lst = ["麻花藤", "岡本次郎", "中央情報局", "狐仙"]
In[11]: lst2 = sorted(lst)
In[12]: lst2
Out[12]: ['中央情報局', '岡本次郎', '狐仙', '麻花藤']
In[14]: print(ord('中'))
20013
In[15]: print(ord('岡'))
20872
In[16]: print(ord('狐'))
29392
In[17]: print(ord('麻'))
40635
filter
filter是python中內置的一個過濾的函數,其用法跟sorted差不多:
filter(function, iterable)
- function: ⽤來篩選的函數. 在filter中會⾃動的把iterable中的元素傳遞給function. 然後
根據function返回的True或者False來判斷是否保留此項數據 - iterable: 可迭代對象
In[21]: lst = [{'id':1,'name':'alex','age':28},
...: {'id':2,'name':'taibai','age':58},
...: {'id':3,'name':'taihei','age':18},
...: {'id':4,'name':'henhei','age':38}]
In[22]: ret2 = filter(lambda x: x['age'] >= 38, lst)
...: [print(x) for x in ret2]
{'id': 2, 'name': 'taibai', 'age': 58} # 從結果來看,年齡小於38的都被過濾掉了
{'id': 4, 'name': 'henhei', 'age': 38}
Out[22]: [None, None]
map
映射函數map,使用語法為:
map(function, iterable)
可以對可迭代對象中的每⼀個元素進⾏映射. 分別取執⾏function(其語法和sorted、filter相似)
In[23]: names=['oldboy','alex','wusir']
In[24]: m = map(lambda s: s + '123', names) # 在每個字元串後加上123
In[25]: print(list(m)) # map返回的也是一個可迭代對象,使用list會去迴圈遍歷元素
['oldboy123', 'alex123', 'wusir123']
三、遞歸
在函數中調⽤函數本⾝. 就是遞歸
def func():
print("我是誰")
func()
func()
在python中最大遞歸深度為1000:
In[26]: import sys
In[27]: sys.getrecursionlimit() # 雖然我們查詢到的結果是1000,但是實際上卻跑不到1000,通常是998或者997
Out[27]: 1000
遞歸的應用:計算斐波那契數列 f(0) = 1 f(1) = 1 f(n) = f(n-1) + f(n-2)
In[35]: def fib(n):
...: if n == 0:
...: return 1
...: if n == 1:
...: return 1
...: return fib(n-1) + fib(n-2)
...:
In[36]: fib(5)
Out[36]: 8
In[37]: fib(10)
Out[37]: 89
總結:
- 遞歸函數總是涉及到壓棧和出棧的過程
- 遞歸函數總是壓棧,知道遇到退出條件,然後出棧
- Python中遞歸函數有深度限制,可以通過
sys.getrecursionlimit()
得到深度限制,可以通過sys.setrecursionlimit
調整遞歸深度限制 - 遞歸函數在Python非常慢,並且有深度限制,所以 因儘量避免使用遞歸
四、二分法查找
⼆分查找. 每次能夠排除掉⼀半的數據. 查找的效率非常⾼. 但是局限性比較⼤. 必須是有
序序列才可以使⽤⼆分查找
- 要求: 查找的序列必須是有序序列
(1) 使用基本的演算法實現:
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
n = int(input("請輸入一個數字n:")) # 56
left = 0 # 左邊界
right = len(lst) - 1 # 末尾的索引 右邊界
while left <= right: # 當左邊界大於右邊界結束迴圈
mid = (left + right) // 2 # 求中間的索引坐標
if n < lst[mid]: # 判斷你的數字和中間數的大小比較 .
right = mid - 1 # 右邊界往左移動
elif n > lst[mid]:
left = mid + 1 # 左邊界往右移動
else:
print("找到了") # 找到了目標數字
break
else: # 當左比右大, 迴圈結束. 沒有找到目標數
print("沒找到")
(2)使用遞歸實現:
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
def binary_search(lst, n, left, right):
if left > right:
return False
mid = (left + right) // 2
if n > lst[mid]:
left = mid + 1
# 當遞歸有返回值的時候. 需要寫return. 否則有可能接收不到返回值
return binary_search(lst, n, left, right)
elif n < lst[mid]:
right = mid - 1
return binary_search(lst, n, left, right)
else:
print("找到了")
return True
n = int(input("請輸入一個數字n:")) # 178
ret = binary_search(lst, n, 0, len(lst)-1)
print(ret)
# 結果:
# 請輸入一個數字n:178
# 找到了
# True
切記:當遞歸有返回值的時候. 需要寫return. 否則有可能接收不到返回值
(3)對列表切片:
def binary_search(lst, n):
if len(lst) == 0:
return False
left = 0
right = len(lst) - 1
mid = (left + right) // 2
if n > lst[mid]:
left = mid + 1
# 當遞歸有返回值的時候. 需要寫return. 否則有可能接收不到返回值
return binary_search(lst[mid+1:], n)
elif n < lst[mid]:
right = mid - 1
return binary_search(lst[:mid], n)
else:
print("找到了")
return True