函數(shù)

函數(shù)(1)

目標(biāo)

  • 函數(shù)的作用
  • 函數(shù)的使用步驟
  • 函數(shù)的參數(shù)作用
  • 函數(shù)的返回值作用
  • 函數(shù)的說明文檔
  • 函數(shù)嵌套

一. 函數(shù)的作用

需求:用戶到ATM機(jī)取錢:

  1. 輸入密碼后顯示"選擇功能"界面
  2. 查詢余額后顯示"選擇功能"界面
  3. 取2000錢后顯示"選擇功能"界面

特點(diǎn):顯示“選擇功能”界面需要重復(fù)輸出給用戶,怎么實(shí)現(xiàn)?

函數(shù)就是將一段具有獨(dú)立功能的代碼塊整合到一個(gè)整體并命名,在需要的位置調(diào)用這個(gè)名稱即可完成對(duì)應(yīng)的需求。

函數(shù)在開發(fā)過程中,可以更高效的實(shí)現(xiàn)代碼重用。

二. 函數(shù)的使用步驟

2.1 定義函數(shù)

def 函數(shù)名(參數(shù)):
    代碼1
    代碼2
    ......

2.2 調(diào)用函數(shù)

函數(shù)名(參數(shù))

注意:
1. 不同的需求,參數(shù)可有可無。
2. 在Python中,函數(shù)必須先定義后使用。

2.3 快速體驗(yàn)

需求:復(fù)現(xiàn)ATM取錢功能。

  1. 搭建整體框架(復(fù)現(xiàn)需求)
print('密碼正確登錄成功')

# 顯示"選擇功能"界面

print('查詢余額完畢')

# 顯示"選擇功能"界面

print('取了2000元錢')

# 顯示"選擇功能"界面
  1. 確定“選擇功能”界面內(nèi)容
print('查詢余額')
print('存款')
print('取款')
  1. 封裝"選擇功能"

注意:一定是先定義函數(shù),后調(diào)用函數(shù)。

# 封裝ATM機(jī)功能選項(xiàng) -- 定義函數(shù)
def select_func():
    print('-----請選擇功能-----')
    print('查詢余額')
    print('存款')
    print('取款')
    print('-----請選擇功能-----')
  1. 調(diào)用函數(shù)

在需要顯示“選擇功能”函數(shù)的位置調(diào)用函數(shù)。

print('密碼正確登錄成功')
# 顯示"選擇功能"界面 -- 調(diào)用函數(shù)
select_func()

print('查詢余額完畢')
# 顯示"選擇功能"界面 -- 調(diào)用函數(shù)
select_func()

print('取了2000元錢')
# 顯示"選擇功能"界面 -- 調(diào)用函數(shù)
select_func()

三.函數(shù)的參數(shù)作用

思考:完成需求如下:一個(gè)函數(shù)完成兩個(gè)數(shù)1和2的加法運(yùn)算,如何書寫程序?

# 定義函數(shù)
def add_num1():
    result = 1 + 2
    print(result)


# 調(diào)用函數(shù)
add_num1()

思考:上述add_num1函數(shù)只能完成數(shù)字1和2的加法運(yùn)算,如果想要這個(gè)函數(shù)變得更靈活,可以計(jì)算任何用戶指定的兩個(gè)數(shù)字的和,如何書寫程序?

分析:用戶要在調(diào)用函數(shù)的時(shí)候指定具體數(shù)字,那么在定義函數(shù)的時(shí)候就需要接收用戶指定的數(shù)字。函數(shù)調(diào)用時(shí)候指定的數(shù)字和定義函數(shù)時(shí)候接收的數(shù)字即是函數(shù)的參數(shù)。

# 定義函數(shù)時(shí)同時(shí)定義了接收用戶數(shù)據(jù)的參數(shù)a和b,a和b是形參
def add_num2(a, b):
    result = a + b
    print(result)


# 調(diào)用函數(shù)時(shí)傳入了真實(shí)的數(shù)據(jù)10 和 20,真實(shí)數(shù)據(jù)為實(shí)參
add_num2(10, 20)

四.函數(shù)的返回值作用

例如:我們?nèi)コ匈徫铮热缳I煙,給錢之后,是不是售貨員會(huì)返回給我們煙這個(gè)商品,在函數(shù)中,如果需要返回結(jié)果給用戶需要使用函數(shù)返回值。

def buy():
    return '煙'

# 使用變量保存函數(shù)返回值
goods = buy()
print(goods)

4.1 應(yīng)用

需求:制作一個(gè)計(jì)算器,計(jì)算任意兩數(shù)字之和,并保存結(jié)果。

def sum_num(a, b):
    return a + b


# 用result變量保存函數(shù)返回值
result = sum_num(1, 2)
print(result)

五.函數(shù)的說明文檔

思考:定義一個(gè)函數(shù)后,程序員如何書寫程序能夠快速提示這個(gè)函數(shù)的作用?

答:注釋

思考:如果代碼多,我們是不是需要在很多代碼中找到這個(gè)函數(shù)定義的位置才能看到注釋?如果想更方便的查看函數(shù)的作用怎么辦?

答:函數(shù)的說明文檔

函數(shù)的說明文檔也叫函數(shù)的文檔說明。

5.1 語法

  • 定義函數(shù)的說明文檔
def 函數(shù)名(參數(shù)):
    """ 說明文檔的位置 """
    代碼
    ......
  • 查看函數(shù)的說明文檔
help(函數(shù)名)

5.2 快速體驗(yàn)

def sum_num(a, b):
    """ 求和函數(shù) """
    return a + b


help(sum_num)

六.函數(shù)嵌套調(diào)用

所謂函數(shù)嵌套調(diào)用指的是==一個(gè)函數(shù)里面又調(diào)用了另外一個(gè)函數(shù)==。

  • 示例
def testB():
    print('---- testB start----')
    print('這里是testB函數(shù)執(zhí)行的代碼...(省略)...')
    print('---- testB end----')

def testA():
    print('---- testA start----')
    testB()
    print('---- testA end----')

testA()
  • 效果


  • 如果函數(shù)A中,調(diào)用了另外一個(gè)函數(shù)B,那么先把函數(shù)B中的任務(wù)都執(zhí)行完畢之后才會(huì)回到上次 函數(shù)A執(zhí)行的位置。

七. 函數(shù)應(yīng)用

7.1 打印圖形

  1. 打印一條橫線
def print_line():
    print('-' * 20)


print_line()
  1. 打印多條橫線
def print_line():
    print('-' * 20)


def print_lines(num):
    i = 0
    while i < num:
        print_line()
        i += 1


print_lines(5)

7.2 函數(shù)計(jì)算

  1. 求三個(gè)數(shù)之和
def sum_num(a, b, c):
    return a + b + c


result = sum_num(1, 2, 3)
print(result)  # 6
  1. 求三個(gè)數(shù)平均值
def average_num(a, b, c):
    sumResult = sum_num(a, b, c)
    return sumResult / 3

result = average_num(1, 2, 3)
print(result)  # 2.0

八. 總結(jié)

  • 函數(shù)的作用:封裝代碼,高效的代碼重用

  • 函數(shù)使用步驟

    • 定義函數(shù)
    def 函數(shù)名():
        代碼1
        代碼2
        ...
    
    • 調(diào)用函數(shù)
    函數(shù)名()
    
  • 函數(shù)的參數(shù):函數(shù)調(diào)用的時(shí)候可以傳入真實(shí)數(shù)據(jù),增大函數(shù)的使用的靈活性

    • 形參:函數(shù)定義時(shí)書寫的參數(shù)(非真實(shí)數(shù)據(jù))
    • 實(shí)參:函數(shù)調(diào)用時(shí)書寫的參數(shù)(真實(shí)數(shù)據(jù))
  • 函數(shù)的返回值

    • 作用:函數(shù)調(diào)用后,返回需要的計(jì)算結(jié)果
    • 寫法
    return 表達(dá)式
    
  • 函數(shù)的說明文檔

    • 作用:保存函數(shù)解釋說明的信息
    • 寫法
    def 函數(shù)名():
        """ 函數(shù)說明文檔 """
    
  • 函數(shù)嵌套調(diào)用:一個(gè)函數(shù)內(nèi)部嵌套調(diào)用另外一個(gè)函數(shù)

函數(shù)(2)

目標(biāo)

  • 變量作用域
  • 多函數(shù)程序執(zhí)行流程
  • 函數(shù)的返回值
  • 函數(shù)的參數(shù)
  • 拆包和交換兩個(gè)變量的值
  • 引用
  • 可變和不可變類型

一. 變量作用域

變量作用域指的是變量生效的范圍,主要分為兩類:==局部變量==和==全局變量==。

  • 局部變量

所謂局部變量是定義在函數(shù)體內(nèi)部的變量,即只在函數(shù)體內(nèi)部生效。

def testA():
    a = 100

    print(a)


testA()  # 100
print(a)  # 報(bào)錯(cuò):name 'a' is not defined

變量a是定義在testA函數(shù)內(nèi)部的變量,在函數(shù)外部訪問則立即報(bào)錯(cuò)。

局部變量的作用:在函數(shù)體內(nèi)部,臨時(shí)保存數(shù)據(jù),即當(dāng)函數(shù)調(diào)用完成后,則銷毀局部變量。

  • 全局變量

所謂全局變量,指的是在函數(shù)體內(nèi)、外都能生效的變量。

思考:如果有一個(gè)數(shù)據(jù),在函數(shù)A和函數(shù)B中都要使用,該怎么辦?

答:將這個(gè)數(shù)據(jù)存儲(chǔ)在一個(gè)全局變量里面。

# 定義全局變量a
a = 100


def testA():
    print(a)  # 訪問全局變量a,并打印變量a存儲(chǔ)的數(shù)據(jù)


def testB():
    print(a)  # 訪問全局變量a,并打印變量a存儲(chǔ)的數(shù)據(jù)


testA()  # 100
testB()  # 100

思考:testB函數(shù)需求修改變量a的值為200,如何修改程序?

a = 100


def testA():
    print(a)


def testB():
    a = 200
    print(a)


testA()  # 100
testB()  # 200
print(f'全局變量a = {a}')  # 全局變量a = 100

思考:在testB函數(shù)內(nèi)部的a = 200中的變量a是在修改全局變量a嗎?

答:不是。觀察上述代碼發(fā)現(xiàn),最后print得到a的數(shù)據(jù)是100,仍然是定義全局變量a時(shí)候的值,而沒有返回

testB函數(shù)內(nèi)部的200。綜上:testB函數(shù)內(nèi)部的a = 200是定義了一個(gè)局部變量。

思考:如何在函數(shù)體內(nèi)部修改全局變量?

a = 100


def testA():
    print(a)


def testB():
    # global 關(guān)鍵字聲明a是全局變量
    global a
    a = 200
    print(a)


testA()  # 100
testB()  # 200
print(f'全局變量a = {a}')  # 全局變量a = 200

二. 多函數(shù)程序執(zhí)行流程

一般在實(shí)際開發(fā)過程中,一個(gè)程序往往由多個(gè)函數(shù)(后面知識(shí)中會(huì)講解類)組成,并且多個(gè)函數(shù)共享某些數(shù)據(jù),如下所示:

  • 共用全局變量
# 1. 定義全局變量
glo_num = 0


def test1():
    global glo_num
    # 修改全局變量
    glo_num = 100


def test2():
    # 調(diào)用test1函數(shù)中修改后的全局變量
    print(glo_num)
    

# 2. 調(diào)用test1函數(shù),執(zhí)行函數(shù)內(nèi)部代碼:聲明和修改全局變量
test1()
# 3. 調(diào)用test2函數(shù),執(zhí)行函數(shù)內(nèi)部代碼:打印
test2()  # 100
  • 返回值作為參數(shù)傳遞
def test1():
    return 50


def test2(num):
    print(num)


# 1. 保存函數(shù)test1的返回值
result = test1()


# 2.將函數(shù)返回值所在變量作為參數(shù)傳遞到test2函數(shù)
test2(result)  # 50

三. 函數(shù)的返回值

思考:如果一個(gè)函數(shù)如些兩個(gè)return (如下所示),程序如何執(zhí)行?

def return_num():
    return 1
    return 2


result = return_num()
print(result)  # 1

答:只執(zhí)行了第一個(gè)return,原因是因?yàn)閞eturn可以退出當(dāng)前函數(shù),導(dǎo)致return下方的代碼不執(zhí)行。

思考:如果一個(gè)函數(shù)要有多個(gè)返回值,該如何書寫代碼?

def return_num():
    return 1, 2


result = return_num()
print(result)  # (1, 2)

注意:

  1. return a, b寫法,返回多個(gè)數(shù)據(jù)的時(shí)候,默認(rèn)是元組類型。
  2. return后面可以連接列表、元組或字典,以返回多個(gè)值。

四. 函數(shù)的參數(shù)

4.1 位置參數(shù)

位置參數(shù):調(diào)用函數(shù)時(shí)根據(jù)函數(shù)定義的參數(shù)位置來傳遞參數(shù)。

def user_info(name, age, gender):
    print(f'您的名字是{name}, 年齡是{age}, 性別是{gender}')


user_info('TOM', 20, '男')

注意:傳遞和定義參數(shù)的順序及個(gè)數(shù)必須一致。

4.2 關(guān)鍵字參數(shù)

函數(shù)調(diào)用,通過“鍵=值”形式加以指定??梢宰尯瘮?shù)更加清晰、容易使用,同時(shí)也清除了參數(shù)的順序需求。

def user_info(name, age, gender):
    print(f'您的名字是{name}, 年齡是{age}, 性別是{gender}')


user_info('Rose', age=20, gender='女')
user_info('小明', gender='男', age=16)

注意:函數(shù)調(diào)用時(shí),如果有位置參數(shù)時(shí),位置參數(shù)必須在關(guān)鍵字參數(shù)的前面,但關(guān)鍵字參數(shù)之間不存在先后順序。

4.3 缺省參數(shù)

缺省參數(shù)也叫默認(rèn)參數(shù),用于定義函數(shù),為參數(shù)提供默認(rèn)值,調(diào)用函數(shù)時(shí)可不傳該默認(rèn)參數(shù)的值(注意:所有位置參數(shù)必須出現(xiàn)在默認(rèn)參數(shù)前,包括函數(shù)定義和調(diào)用)。

def user_info(name, age, gender='男'):
    print(f'您的名字是{name}, 年齡是{age}, 性別是{gender}')


user_info('TOM', 20)
user_info('Rose', 18, '女')

注意:函數(shù)調(diào)用時(shí),如果為缺省參數(shù)傳值則修改默認(rèn)參數(shù)值;否則使用這個(gè)默認(rèn)值。

4.4 不定長參數(shù)

不定長參數(shù)也叫可變參數(shù)。用于不確定調(diào)用的時(shí)候會(huì)傳遞多少個(gè)參數(shù)(不傳參也可以)的場景。此時(shí),可用包裹(packing)位置參數(shù),或者包裹關(guān)鍵字參數(shù),來進(jìn)行參數(shù)傳遞,會(huì)顯得非常方便。

  • 包裹位置傳遞
def user_info(*args):
    print(args)


# ('TOM',)
user_info('TOM')
# ('TOM', 18)
user_info('TOM', 18)

注意:傳進(jìn)的所有參數(shù)都會(huì)被args變量收集,它會(huì)根據(jù)傳進(jìn)參數(shù)的位置合并為一個(gè)元組(tuple),args是元組類型,這就是包裹位置傳遞。

  • 包裹關(guān)鍵字傳遞
def user_info(**kwargs):
    print(kwargs)


# {'name': 'TOM', 'age': 18, 'id': 110}
user_info(name='TOM', age=18, id=110)

綜上:無論是包裹位置傳遞還是包裹關(guān)鍵字傳遞,都是一個(gè)組包的過程。

五. 拆包和交換變量值

5.1 拆包

  • 拆包:元組
def return_num():
    return 100, 200


num1, num2 = return_num()
print(num1)  # 100
print(num2)  # 200
  • 拆包:字典
dict1 = {'name': 'TOM', 'age': 18}
a, b = dict1

# 對(duì)字典進(jìn)行拆包,取出來的是字典的key
print(a)  # name
print(b)  # age

print(dict1[a])  # TOM
print(dict1[b])  # 18

5.2 交換變量值

需求:有變量a = 10b = 20,交換兩個(gè)變量的值。

  • 方法一

借助第三變量存儲(chǔ)數(shù)據(jù)。

# 1. 定義中間變量
c = 0

# 2. 將a的數(shù)據(jù)存儲(chǔ)到c
c = a

# 3. 將b的數(shù)據(jù)20賦值到a,此時(shí)a = 20
a = b

# 4. 將之前c的數(shù)據(jù)10賦值到b,此時(shí)b = 10
b = c

print(a)  # 20
print(b)  # 10
  • 方法二
a, b = 1, 2
a, b = b, a
print(a)  # 2
print(b)  # 1

六. 引用

6.1 了解引用

在python中,值是靠引用來傳遞來的。

我們可以用id()來判斷兩個(gè)變量是否為同一個(gè)值的引用。 我們可以將id值理解為那塊內(nèi)存的地址標(biāo)識(shí)。

# 1. int類型
a = 1
b = a

print(b)  # 1

print(id(a))  # 140708464157520
print(id(b))  # 140708464157520

a = 2
print(b)  # 1,說明int類型為不可變類型 

print(id(a))  # 140708464157552,此時(shí)得到是的數(shù)據(jù)2的內(nèi)存地址
print(id(b))  # 140708464157520


# 2. 列表
aa = [10, 20]
bb = aa

print(id(aa))  # 2325297783432
print(id(bb))  # 2325297783432


aa.append(30)
print(bb)  # [10, 20, 30], 列表為可變類型

print(id(aa))  # 2325297783432
print(id(bb))  # 2325297783432

6.2 引用當(dāng)做實(shí)參

代碼如下:

def test1(a):
    print(a)
    print(id(a))

    a += a

    print(a)
    print(id(a))


# int:計(jì)算前后id值不同
b = 100
test1(b)

# 列表:計(jì)算前后id值相同
c = [11, 22]
test1(c)

七. 可變和不可變類型

所謂可變類型與不可變類型是指:數(shù)據(jù)能夠直接進(jìn)行修改,如果能直接修改那么就是可變,否則是不可變.

  • 可變類型
    • 列表
    • 字典
    • 集合
  • 不可變類型
    • 整型
    • 浮點(diǎn)型
    • 字符串
    • 元組

八. 總結(jié)

  • 變量作用域
    • 全局:函數(shù)體內(nèi)外都能生效
    • 局部:當(dāng)前函數(shù)體內(nèi)部生效
  • 函數(shù)多返回值寫法
return 表達(dá)式1, 表達(dá)式2...
  • 函數(shù)的參數(shù)
    • 位置參數(shù)
      • 形參和實(shí)參的個(gè)數(shù)和書寫順序必須一致
    • 關(guān)鍵字參數(shù)
      • 寫法: key=value
      • 特點(diǎn):形參和實(shí)參的書寫順序可以不一致;關(guān)鍵字參數(shù)必須書寫在位置參數(shù)的后面
    • 缺省參數(shù)
      • 缺省參數(shù)就是默認(rèn)參數(shù)
      • 寫法:key=vlaue
    • 不定長位置參數(shù)
      • 收集所有位置參數(shù),返回一個(gè)元組
    • 不定長關(guān)鍵字參數(shù)
      • 收集所有關(guān)鍵字參數(shù),返回一個(gè)字典
  • 引用:Python中,數(shù)據(jù)的傳遞都是通過引用

函數(shù)(3)

目標(biāo)

  • 應(yīng)用:學(xué)員管理系統(tǒng)
  • 遞歸
  • lambda 表達(dá)式
  • 高階函數(shù)

一. 應(yīng)用:學(xué)員管理系統(tǒng)

1.1 系統(tǒng)簡介

需求:進(jìn)入系統(tǒng)顯示系統(tǒng)功能界面,功能如下:

  • 1、添加學(xué)員
  • 2、刪除學(xué)員
  • 3、修改學(xué)員信息
  • 4、查詢學(xué)員信息
  • 5、顯示所有學(xué)員信息
  • 6、退出系統(tǒng)

系統(tǒng)共6個(gè)功能,用戶根據(jù)自己需求選取。

1.2 步驟分析

  1. 顯示功能界面

  2. 用戶輸入功能序號(hào)

  3. 根據(jù)用戶輸入的功能序號(hào),執(zhí)行不同的功能(函數(shù))

    3.1 定義函數(shù)

    3.2 調(diào)用函數(shù)

1.3 需求實(shí)現(xiàn)

1.3.1 顯示功能界面

定義函數(shù)print_info,負(fù)責(zé)顯示系統(tǒng)功能。

def print_info():
    print('-' * 20)
    print('歡迎登錄學(xué)員管理系統(tǒng)')
    print('1: 添加學(xué)員')
    print('2: 刪除學(xué)員')
    print('3: 修改學(xué)員信息')
    print('4: 查詢學(xué)員信息')
    print('5: 顯示所有學(xué)員信息')
    print('6: 退出系統(tǒng)')
    print('-' * 20)
    
    
print_info()

1.3.2 用戶輸入序號(hào),選擇功能

user_num = input('請選擇您需要的功能序號(hào):')

1.3.3 根據(jù)用戶選擇,執(zhí)行不同的功能

if user_num == '1':
    print('添加學(xué)員')
elif user_num == '2':
    print('刪除學(xué)員')
elif user_num == '3':
    print('修改學(xué)員信息')
elif user_num == '4':
    print('查詢學(xué)員信息')
elif user_num == '5':
    print('顯示所有學(xué)員信息')
elif user_num == '6':
    print('退出系統(tǒng)')

工作中,需要根據(jù)實(shí)際需求調(diào)優(yōu)代碼。

  1. 用戶選擇系統(tǒng)功能的代碼需要循環(huán)使用,直到用戶主動(dòng)退出系統(tǒng)。
  2. 如果用戶輸入1-6以外的數(shù)字,需要提示用戶。
while True:
    # 1. 顯示功能界面
    print_info()
    
    # 2. 用戶選擇功能
    user_num = input('請選擇您需要的功能序號(hào):')

    # 3. 根據(jù)用戶選擇,執(zhí)行不同的功能
    if user_num == '1':
        print('添加學(xué)員')
    elif user_num == '2':
        print('刪除學(xué)員')
    elif user_num == '3':
        print('修改學(xué)員信息')
    elif user_num == '4':
        print('查詢學(xué)員信息')
    elif user_num == '5':
        print('顯示所有學(xué)員信息')
    elif user_num == '6':
        print('退出系統(tǒng)')
    else:
        print('輸入錯(cuò)誤,請重新輸入!!!')

1.3.4 定義不同功能的函數(shù)

所有功能函數(shù)都是操作學(xué)員信息,所有存儲(chǔ)所有學(xué)員信息應(yīng)該是一個(gè)全局變量,數(shù)據(jù)類型為列表。

info = []

1.3.4.1 添加學(xué)員

  • 需求分析
  1. 接收用戶輸入學(xué)員信息,并保存

  2. 判斷是否添加學(xué)員信息

    2.1 如果學(xué)員姓名已經(jīng)存在,則報(bào)錯(cuò)提示

    2.2 如果學(xué)員姓名不存在,則準(zhǔn)備空字典,將用戶輸入的數(shù)據(jù)追加到字典,再列表追加字典數(shù)據(jù)

  3. 對(duì)應(yīng)的if條件成立的位置調(diào)用該函數(shù)

  • 代碼實(shí)現(xiàn)
def add_info():
    """ 添加學(xué)員 """
    # 接收用戶輸入學(xué)員信息
    new_id = input('請輸入學(xué)號(hào):')
    new_name = input('請輸入姓名:')
    new_tel = input('請輸入手機(jī)號(hào):')
    

    # 聲明info是全局變量
    global info

    # 檢測用戶輸入的姓名是否存在,存在則報(bào)錯(cuò)提示
    for i in info:
        if new_name == i['name']:
            print('該用戶已經(jīng)存在!')
            return

    # 如果用戶輸入的姓名不存在,則添加該學(xué)員信息
    info_dict = {}
    
    # 將用戶輸入的數(shù)據(jù)追加到字典
    info_dict['id'] = new_id
    info_dict['name'] = new_name
    info_dict['tel'] = new_tel
    
    # 將這個(gè)學(xué)員的字典數(shù)據(jù)追加到列表
    info.append(info_dict)
    
    print(info)

1.3.4.2 刪除學(xué)員

  • 需求分析

按用戶輸入的學(xué)員姓名進(jìn)行刪除

  1. 用戶輸入目標(biāo)學(xué)員姓名

  2. 檢查這個(gè)學(xué)員是否存在

    2.1 如果存在,則列表刪除這個(gè)數(shù)據(jù)

    2.2 如果不存在,則提示“該用戶不存在”

  3. 對(duì)應(yīng)的if條件成立的位置調(diào)用該函數(shù)

  • 代碼實(shí)現(xiàn)
# 刪除學(xué)員
def del_info():
    """刪除學(xué)員"""
    # 1. 用戶輸入要?jiǎng)h除的學(xué)員的姓名
    del_name = input('請輸入要?jiǎng)h除的學(xué)員的姓名:')

    global info
    # 2. 判斷學(xué)員是否存在:如果輸入的姓名存在則刪除,否則報(bào)錯(cuò)提示
    for i in info:
        if del_name == i['name']:
            info.remove(i)
            break
    else:
        print('該學(xué)員不存在')

    print(info)

1.3.4.3 修改學(xué)員信息

  • 需求分析
  1. 用戶輸入目標(biāo)學(xué)員姓名

  2. 檢查這個(gè)學(xué)員是否存在

    2.1 如果存在,則修改這位學(xué)員的信息,例如手機(jī)號(hào)

    2.2 如果不存在,則報(bào)錯(cuò)

  3. 對(duì)應(yīng)的if條件成立的位置調(diào)用該函數(shù)

  • 代碼實(shí)現(xiàn)
# 修改函數(shù)
def modify_info():
    """修改函數(shù)"""
    # 1. 用戶輸入要修改的學(xué)員的姓名
    modify_name = input('請輸入要修改的學(xué)員的姓名:')

    global info
    # 2. 判斷學(xué)員是否存在:如果輸入的姓名存在則修改手機(jī)號(hào),否則報(bào)錯(cuò)提示
    for i in info:
        if modify_name == i ['name']:
            i['tel'] = input('請輸入新的手機(jī)號(hào):')
            break
    else:
        print('該學(xué)員不存在')
    
    print(info)

1.3.4.4 查詢學(xué)員信息

  • 需求分析
  1. 用戶輸入目標(biāo)學(xué)員姓名

  2. 檢查學(xué)員是否存在

    2.1 如果存在,則顯示這個(gè)學(xué)員的信息

    2.2 如果不存在,則報(bào)錯(cuò)提示

  3. 對(duì)應(yīng)的if條件成立的位置調(diào)用該函數(shù)

  • 代碼實(shí)現(xiàn)
# 查詢學(xué)員
def search_info():
    """查詢學(xué)員"""
    # 1. 輸入要查找的學(xué)員姓名:
    search_name = input('請輸入要查找的學(xué)員姓名:')

    global info
    # 2. 判斷學(xué)員是否存在:如果輸入的姓名存在則顯示這位學(xué)員信息,否則報(bào)錯(cuò)提示
    for i in info:
        if search_name == i['name']:
            print('查找到的學(xué)員信息如下:----------')
            print(f"該學(xué)員的學(xué)號(hào)是{i['id']}, 姓名是{i['name']}, 手機(jī)號(hào)是{i['tel']}")
            break
    else:
        print('該學(xué)員不存在')

1.3.4.5 顯示所有學(xué)員信息

  • 需求分析

打印所有學(xué)員信息

  • 代碼實(shí)現(xiàn)
# 顯示所有學(xué)員信息
def print_all():
    """ 顯示所有學(xué)員信息 """
    print('學(xué)號(hào)\t姓名\t手機(jī)號(hào)')
    for i in info:
        print(f'{i["id"]}\t{i["name"]}\t{i["tel"]}')

1.3.4.6 退出系統(tǒng)

在用戶輸入功能序號(hào)6的時(shí)候要退出系統(tǒng),代碼如下:

    ......
    elif user_num == '6':
        exit_flag = input('確定要退出嗎?yes or no')
        if exit_flag == 'yes':
            break

二. 遞歸

2.1 遞歸的應(yīng)用場景

遞歸是一種編程思想,應(yīng)用場景:

  1. 在我們?nèi)粘i_發(fā)中,如果要遍歷一個(gè)文件夾下面所有的文件,通常會(huì)使用遞歸來實(shí)現(xiàn);
  2. 在后續(xù)的算法課程中,很多算法都離不開遞歸,例如:快速排序。

2.1.1 遞歸的特點(diǎn)

  • 函數(shù)內(nèi)部自己調(diào)用自己
  • 必須有出口

2.2 應(yīng)用:3以內(nèi)數(shù)字累加和

  • 代碼
# 3 + 2 + 1
def sum_numbers(num):
    # 1.如果是1,直接返回1 -- 出口
    if num == 1:
        return 1
    # 2.如果不是1,重復(fù)執(zhí)行累加并返回結(jié)果
    return num + sum_numbers(num-1)


sum_result = sum_numbers(3)
# 輸出結(jié)果為6
print(sum_result)

三. lambda 表達(dá)式

3.1 lambda的應(yīng)用場景

如果一個(gè)函數(shù)有一個(gè)返回值,并且只有一句代碼,可以使用 lambda簡化。

3.2 lambda語法

lambda 參數(shù)列表 : 表達(dá)式

注意
1.lambda表達(dá)式的參數(shù)可有可無,函數(shù)的參數(shù)在lambda表達(dá)式中完全適用。
2.lambda表達(dá)式能接收任何數(shù)量的參數(shù)但只能返回一個(gè)表達(dá)式的值。

快速入門

# 函數(shù)
def fn1():
    return 200


print(fn1)
print(fn1())


# lambda表達(dá)式
fn2 = lambda: 100
print(fn2)
print(fn2())

注意:直接打印lambda表達(dá)式,輸出的是此lambda的內(nèi)存地址

3.3 示例:計(jì)算a + b

3.3.1 函數(shù)實(shí)現(xiàn)

def add(a, b):
    return a + b


result = add(1, 2)
print(result)

思考:需求簡單,是否代碼多?

3.3.2 lambda實(shí)現(xiàn)

fn1 = lambda a, b: a + b
print(fn1(1, 2))

3.4 lambda的參數(shù)形式

3.4.1.無參數(shù)

fn1 = lambda: 100
print(fn1())

3.4.2.一個(gè)參數(shù)

fn1 = lambda a: a
print(fn1('hello world'))

3.4.3.默認(rèn)參數(shù)

fn1 = lambda a, b, c=100: a + b + c
print(fn1(10, 20))

3.4.4.可變參數(shù):*args

fn1 = lambda *args: args
print(fn1(10, 20, 30))

注意:這里的可變參數(shù)傳入到lambda之后,返回值為元組。

3.4.5.可變參數(shù):**kwargs

fn1 = lambda **kwargs: kwargs
print(fn1(name='python', age=20))

3.5 lambda的應(yīng)用

3.5.1. 帶判斷的lambda

fn1 = lambda a, b: a if a > b else b
print(fn1(1000, 500))

3.5.2. 列表數(shù)據(jù)按字典key的值排序

students = [
    {'name': 'TOM', 'age': 20},
    {'name': 'ROSE', 'age': 19},
    {'name': 'Jack', 'age': 22}
]

# 按name值升序排列
students.sort(key=lambda x: x['name'])
print(students)

# 按name值降序排列
students.sort(key=lambda x: x['name'], reverse=True)
print(students)

# 按age值升序排列
students.sort(key=lambda x: x['age'])
print(students)

四. 高階函數(shù)

把函數(shù)作為參數(shù)傳入,這樣的函數(shù)稱為高階函數(shù),高階函數(shù)是函數(shù)式編程的體現(xiàn)。函數(shù)式編程就是指這種高度抽象的編程范式。

4.1 體驗(yàn)高階函數(shù)

在Python中,abs()函數(shù)可以完成對(duì)數(shù)字求絕對(duì)值計(jì)算。

abs(-10)  # 10

round()函數(shù)可以完成對(duì)數(shù)字的四舍五入計(jì)算。

round(1.2)  # 1
round(1.9)  # 2

需求:任意兩個(gè)數(shù)字,按照指定要求整理數(shù)字后再進(jìn)行求和計(jì)算。

  • 方法1
def add_num(a, b):
    return abs(a) + abs(b)


result = add_num(-1, 2)
print(result)  # 3
  • 方法2
def sum_num(a, b, f):
    return f(a) + f(b)


result = sum_num(-1, 2, abs)
print(result)  # 3

注意:兩種方法對(duì)比之后,發(fā)現(xiàn),方法2的代碼會(huì)更加簡潔,函數(shù)靈活性更高。

函數(shù)式編程大量使用函數(shù),減少了代碼的重復(fù),因此程序比較短,開發(fā)速度較快。

4.2 內(nèi)置高階函數(shù)

4.2.1 map()

map(func, lst),將傳入的函數(shù)變量func作用到lst變量的每個(gè)元素中,并將結(jié)果組成新的列表(Python2)/迭代器(Python3)返回。

需求:計(jì)算list1序列中各個(gè)數(shù)字的2次方。

list1 = [1, 2, 3, 4, 5]


def func(x):
    return x ** 2


result = map(func, list1)

print(result)  # <map object at 0x0000013769653198>
print(list(result))  # [1, 4, 9, 16, 25]

4.2.2 reduce()

reduce(func,lst),其中func必須有兩個(gè)參數(shù)。每次func計(jì)算的結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算。

注意:reduce()傳入的參數(shù)func必須接收2個(gè)參數(shù)。

需求:計(jì)算list1序列中各個(gè)數(shù)字的累加和。

import functools

list1 = [1, 2, 3, 4, 5]


def func(a, b):
    return a + b


result = functools.reduce(func, list1)

print(result)  # 15

4.2.3 filter()

filter(func, lst)函數(shù)用于過濾序列, 過濾掉不符合條件的元素, 返回一個(gè) filter 對(duì)象。如果要轉(zhuǎn)換為列表, 可以使用 list() 來轉(zhuǎn)換。

list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def func(x):
    return x % 2 == 0


result = filter(func, list1)

print(result)  # <filter object at 0x0000017AF9DC3198>
print(list(result))  # [2, 4, 6, 8, 10]

五. 總結(jié)

  • 遞歸

    • 函數(shù)內(nèi)部自己調(diào)用自己
    • 必須有出口
  • lambda

    • 語法
    lambda 參數(shù)列表: 表達(dá)式
    
    • lambda的參數(shù)形式

      • 無參數(shù)
      lambda: 表達(dá)式
      
      • 一個(gè)參數(shù)
      lambda 參數(shù): 表達(dá)式
      
      • 默認(rèn)參數(shù)
      lambda key=value: 表達(dá)式
      
      • 不定長位置參數(shù)
      lambda *args: 表達(dá)式
      
      • 不定長關(guān)鍵字參數(shù)
      lambda **kwargs: 表達(dá)式
      
  • 高階函數(shù)

    • 作用:把函數(shù)作為參數(shù)傳入,化簡代碼
    • 內(nèi)置高階函數(shù)
      • map()
      • reduce()
      • filter()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容