Python基礎學習筆記——函數(4):遞歸函數、匿名函數、高階函數

函數

遞歸函數

  • 定義:在函數內部調用函數自身的函數稱爲遞歸函數。
  • 達到終止條件時,函數逐層結束運算,返回計算結果,要注意終止條件的構建,不然會出現無限遞歸,程序報錯。
  • 特色:可以很是簡潔的解決複雜問題,每次函數調用時,函數參數會臨時儲存,相互沒有影響。
# 例子:階乘
def calc_num(num):
    if num == 1:
        # 若是計算1的階乘,直接返回結果
        return 1
    else:
        return num * calc_num(num-1)
result = calc_num(3)
print(result)

Python中遞歸的缺點:就是遞歸有上限控制,默認是1000次,實際997或者998次就已經不能再調用本身了,並報錯。python

設置Python遞歸默認的遞歸次數上限
  • 注意:設置僅本次有效,程序一關就失效了。
import sys
# 獲取默認的遞歸次數
result = sys.getrecursionlimit()
print(result)
# 修改默認的遞歸次數
sys.setrecursionlimit(1200)

遞歸函數的調用過程

在這裏插入圖片描述

匿名函數(lamdba)

  • 定義:沒有名字的函數能夠稱爲匿名函數或者使用lambda關鍵字定義的函數也能夠稱爲匿名函數,匿名函數也是函數,只是特殊的函數而已。
  • lambda函數是一種快速定義單行的最小函數,是從Lisp語言借來的,能夠用在任何須要函數的地方。
特色:
  1. 能夠簡化函數的代碼實現,匿名函數只能寫一行代碼;
  2. 匿名函數返回結果不須要使用return關鍵字;
  3. 使用python寫一些執行腳本時,使用lambda能夠省去定義函數的過程,讓代碼更加精簡;
  4. 對於一些抽象的,不會在別的地方再重複使用的函數,有時候給函數起個名字也是個難題,使用lambda不須要考慮命名的問題;
  5. 使用lambda在某些時候讓代碼更容易理解
使用方法:
  • 用於簡單的,可以在一行內表示的函數,表達式爲返回值或者調用其餘函數;
  • 在Python裏面能夠使用變量保存了一個函數(匿名函數);
  • 匿名函數只能實現簡單的功能操做,表達式不能實現複雜的功能操做,好比: 不能循環,不能使用if語句。
語法格式
變量 = lambda<參數列表>: <表達式>

函數

new_func = lambda num1, num2: num1 + num2
print(type(new_func))  # <class 'function'>
result = new_func(1, 2)  # 執行匿名函數
print(result)  # 3

匿名函數的應用場景

  • 應用:匿名函數能夠做爲參數給另一個函數去使用;
注意:
  • 普通函數也能夠做爲參數給另一個函數去使用;
  • 函數接收一個函數類型的參數,那麼傳參的時候只寫函數名便可,不須要加上小括號,加小括號表示執行。
def calc_num(new_func):  # new_func表示要接收一個函數類型的參數
    n1 = 1
    n2 = 2
    result = new_func(n1, n2)
    print("計算的結果爲:", result)
    
# 使用匿名函數做爲參數給另一個函數使用
calc_num(lambda x, y: x + y)

高階函數

定義:
  1. 函數的參數是一個函數類型,那麼這樣定義的函數是高階函數;
  2. 函數的返回值是一個函數類型,那麼這樣定義的函數也是高階函數;
  3. 函數的參數和返回值都是函數類型,那麼這樣定義的函數仍是高階函數;
  • 特色:函數的參數或者返回值都是一個函數類型
  • 提示:函數的參數和返回值均可以是一個函數類型
# 1、函數的參數要接收的是一個函數類型,那麼這樣的函數就是高階函數
def calc_num(new_func):
    # new_func = 函數(lambda x, y: x - y)
    num1 = 1
    num2 = 2
    result = new_func(num1, num2)
    print(result)
def sum_num(num1, num2):
    return num1 + num2

# sum_num這個函數做爲參數,傳遞給calc_num這個函數去使用
calc_num(sum_num)
# 提示: 若是函數只使用一次,而且還要做爲函數的參數使用
# 那麼這樣函數能夠定義爲匿名函數
calc_num(lambda x, y: x - y)

# 2、函數的返回值是一個函數類型
def show():   # (這個函數實際上是裝飾器,具體能夠查看Python進階學習筆記——裝飾器)
    # 在函數內部還能夠再次定義一個函數,這樣的函數能夠稱爲函數嵌套
    def inner():
        print("內部函數")
    # 返回值是函數類型
    return inner
    
# 調用函數,只是返回內部函數
new_func = show()
print(type(new_func), new_func)  
# <class 'function'> <function show.<locals>.inner at 0x0000027FD32A8510>
# 此時才至關於執行內部函數
new_func()

內置高階函數

reduce() 概括、減小、下降

  • 功能:根據指定函數的功能,完成指定容器類型中每個數據的相關計算。前兩個數結果再與下一個數執行函數。
  • 注意reduce()接收的函數類型必需要有兩個參數(不能多不能少)。
# 導入函數工具包
import functools

# 經過該函數,完成容器類型中的每個數據的拼接操做
my_tuple = ('a', 'b', 'c')
def my_join(param1, param2):
    result = param1 + param2
    return result

result = functools.reduce(my_join, my_tuple)
print(result, type(result))  # abc <class 'str'>

# 用reduce()作階梯加法的:1,2,3,4,5 1+2 3+3 6+4 10+5
from functools import reduce    #reduce 函數在functools模塊中
def f(x, y): 
    return x+y
reduce(f, [1,2,3,4,5,6])

# f函數就爲了生成個參數,因此沒有必要定義函數,能夠直接改爲匿名函數
f = lambda x,y : x+y  #返回的是一個函數
reduce(f, [1,2,3,4,5,6])

filter() 過濾

  • 功能:根據函數的功能對容器類型中的數據進行過濾操做,True獲取,False丟棄。
my_list = [1, 3, 0, 2, 4]

def max_value(value):
    return value > 2

# 遍歷容器類型中的每個數據,把數據交給指定函數進行比較
# 判斷是否獲取傳入的數據:True獲取,False丟棄。
new_filter = filter(max_value, my_list)
print(new_filter)  # <filter object at 0x000001C351C53278>
# 把filter類型轉成列表類型便可,就能獲取過濾的結果了
result = list(new_filter)
print(result)  # [3, 4]

# max_value這種簡單的函數能夠直接使用匿名函數代替
new_filter = filter(lambda x: x > 2, my_list)

# 擴展:遍歷my_list裏面的每個數據,把每個字典數據交給匿名函數進行判斷,
# 條件成立的保存,不然就過濾掉這個數據
my_list = [{"name": "張三", "age": 20}, {"name": "李四", "age": 22}]
new_filter = filter(lambda my_dict: my_dict["age"] > 20, my_list)
new_list = list(new_filter)
print(new_list)  # [{'name': '李四', 'age': 22}]

map()

  • 功能:對列表的每個函數進行函數操做,詳情能夠在本文搜索「列表解析式和生成表達式(列表推導式)」中的「建議」。
相關文章
相關標籤/搜索