函數進階,遞歸,二分法查找

匿名函數

語法:lambda 參數: 返回值

函數沒有具體的名稱,統一稱爲lambda,通常咱們把那個等價的變量當作函數來調用程序員

#求n的平方
a = lambda n : n * n
print(a(9)) # 81



a = lambda x,y : (x,y) # 兩個參數以上的須要將返回值劃爲一個總體,不然會報錯
print(a(250,38))# 250,38

repr()

功能:返回一個對象的string形式(原形畢露)

print("你好. 我叫周潤發") # 你好. 我叫周潤發      對用戶是友好的. 非正式的字符串
# 正式(官方)的字符串, 面向對象的時候
print(repr("你好, 我叫周潤發")) # '你好, 我叫周潤發'
#程序中內部存儲的內容, 這個是給程序員看的

print("我叫%r" % "周潤發") # %r 實際上調用的是repr()
# 原樣輸出
# print(r"馬化騰說:\"哈哈哈, \" \n\t")# 馬化騰說:\"哈哈哈, \" \n\t

print("你好") # 用戶看着舒服
print(repr("你好")) # 真實的字符串表示形式(正式的)

sorted()

功能:排序函數

語法:sorted(iterable, key, reverse(默認值是False))數據結構

key: 排序規則,排序方案ide

運行流程: 把可迭代對象中的每個元素交給後面key函數來執行.
獲得一個數字(權重). 經過這個數字進行排序函數

lst = [16, 18, 32, 54, 12, 9]
s = sorted(lst)
print(s) # [9, 12, 16, 18, 32, 54]

#根據元素長度排序
lst = ["聊齋", "西遊記", "三國演義", "葫蘆娃", "水滸傳", "年輪", "亮劍"]

def func(s):
    return len(s)
ll = sorted(lst,key=func)
print(ll)   #['聊齋', '年輪', '亮劍', '西遊記', '葫蘆娃', '水滸傳', '三國演義'] 


#根據字典中年齡排序
lst = [
    {'name':"汪峯","age":48},
    {"name":"章子怡",'age':38},
    {"name":"alex","age":39},
    {"name":"wusir","age":32},
    {"name":"趙一寧","age":28}
    ]

ll = sorted(lst, key=lambda el: el['age'], reverse=True) #降序
print(ll)
#
[{'name': '汪峯', 'age': 48}, {'name': 'alex', 'age': 39}, {'name': '章子怡', 'age': 38}, {'name': 'wusir', 'age': 32}, {'name': '趙一寧', 'age': 28}]

filter()

功能:過濾,篩選

#去除其中姓張的人
lst = ["張無忌", "張鐵林", "林俊杰", "周杰倫","張先生"]
def func(el):
    if el[0] == '':
        return False # 不想要的
    else:
        return True # 想要的
f = filter(lambda el: el[0]!="", lst) # 將lst中的每一項傳遞給func, 全部返回True的都會保留, 全部返回False都會被過濾掉
print("__iter__" in dir(f)) # 判斷是否能夠進行迭代
for e in f:
    print(e) #    林俊杰
                  # 周杰倫    



lst = [
    {"name":"汪峯", "score":48},
    {"name":"章子怡", "score":39},
    {"name":"周杰倫","score":97},
    {"name":"林俊杰","score":90}
]

f = filter(lambda el: el['score'] < 60 , lst) # 去除低於60的人
print(list(f))   # [{'name': '汪峯', 'score': 48}, {'name': '章子怡', 'score': 39}]

** map()

功能:第一個參數 function 以參數序列中的每個元素調用 function 函數,返回包含每次 function 函數返回值的新列表

語法:map(function, iterable, ...)spa

  • function -- 函數,有兩個參數
  • iterable -- 一個或多個序列
#計算列表中每一個元素的平方
lst = [1,4,7,2,5,8]
def func(el):
    return el**2
m = map(lambda el: el**2, lst) # 把後面的可迭代對象中的每個元素傳遞給function, 結果就是function的返回值
print(list(m)) # >>> [1, 16, 49, 4, 25, 64]


#兩個列表按位置相加
lst1 = [1, 3, 5, 7]
lst2 = [2, 4, 6, 8, 10]
# 水桶效應 只能取到長度最短的那個
m = map(lambda x, y: x + y, lst1, lst2)
print(list(m)) #>>>[3, 7, 11, 15]
 map思想:
分而治之
語法:map(函數1, map(函數2, map(函數3 , lst)))

** 遞歸

語法:code

def lg():
    lg()
lg()
View Code

通俗來說,就是函數內部本身調用本身,造成一個死循環,不過這個死循環是有限度的,上限是1000次,到不了1000就停了對象

緣由:使用遞歸函數須要注意防止棧溢出。在計算機中,函數調用是經過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出blog

count = 1
def func():
    global count
    print("alex是很帥的", count)
    count = count + 1
    func()
func()
>>>#count 一直到996才停
遍歷 D:/sylar文件夾, 打印出全部的文件和普通文件的文件名
import os
def func(filepath, n): # d:/sylar/

    files = os.listdir(filepath) # 1,打開這個文件夾

    for file in files:  # 文件名 # 2. 拿到每個文件名

        f_d = os.path.join(filepath, file) # d:/sylar/文件名/ # 3. 獲取到路徑 
        
        if os.path.isdir(f_d): # 4. 判斷是不是文件夾

            print("\t"*n, file,":") # 打印文件名

             func(f_d, n + 1)  #   5. 若是是文件夾. 繼續再來一遍 
 
        else:   #  不是文件夾. 普通文件
             print("\t"*n, file)        
func("d:/sylar",0)

** 二分法查找

核心思想:掐頭去尾取中間,一次砍掉一半,大大提升查找效率

由於其前提條件,能夠和冒泡排序搭配使用

# 查找一個數n是否在這個序列中,使用二分法能夠提升效率, 前提條件:有序序列
lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789]
n = 88
left = 0             #左邊邊界
right = len(lst)-1 #肯定右邊邊界
while left <= right: # 邊界, 當右邊比左邊還小的時候退出循環
    mid = (left + right)//2 # 必須是整除. 由於索引沒有小數
    if lst[mid] > n:
        right = mid - 1
    if lst[mid] < n:
        left = mid + 1
    if lst[mid] == n:
        print("找到了這個數")
        break
else:
    print("沒有這個數")


# 遞歸來完成二分法
lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789]
def func(n, left, right):
    if left <= right: # 邊界
        print("哈哈")
        mid = (left + right)//2
        if n > lst[mid]:
            left = mid + 1
            return func(n, left, right) # 遞歸  遞歸的入口
        elif n < lst[mid]:
            right = mid - 1
            # 深坑. 函數的返回值返回給調用者
            return func(n, left, right)    # 遞歸
        elif n == lst[mid]:
            print("找到了")
            return mid
            # return  # 經過return返回. 終止遞歸
    else:
        print("沒有這個數") # 遞歸的出口
        return -1 # 1, 索引+ 2, 什麼都不返回, None
# 找66, 左邊界:0,  右邊界是:len(lst) - 1
ret = func(70, 0, len(lst) - 1)
print(ret) # 不是None   前提:必須每層都有一個返回值,若是最後給return,依然是None,
                #由於return返回的值是向上一層返回的
相關文章
相關標籤/搜索