31天Python入門——第9天:再學函數

在這里插入圖片描述

你好,我是安然無虞。

文章目錄

    • 再學函數
      • 1. 變量在函數中的作用域
      • 2. 函數的參數傳遞.
        • 補充學習: 不定長參數*args和**kwargs
      • 3. 值傳遞和引用傳遞
        • 補充學習: 把函數作為參數傳遞
      • 4. 匿名函數
      • 5. python中內置的常用函數
        • zip()
        • map()
        • filter()
        • all()
        • any()
      • 6. 函數練習

在這里插入圖片描述

再學函數

1. 變量在函數中的作用域

變量的作用域是指變量的作用范圍.

局部變量: 在函數體或局部范圍內聲明的變量稱為局部變量.局部變量僅在局部作用域內有效.

全局變量: 在函數之外或在全局范圍內聲明的變量稱為全局變量.全局變量允許在函數內部和外部訪問,但是不允許在函數內部修改.

golbal: 用于在函數內部訪問和修改全局作用域中的變量.通過在函數內部使用 global 關鍵字聲明變量,該變量就可以在函數內部被修改,并且修改后的值也會影響到全局作用域中的變量.

x = 10def modify_global_variable():global xx = 20print(x)
modify_global_variable()
print(x)

nonlocal: 用于在嵌套函數中修改嵌套作用域外的變量。它允許你在內部函數中訪問并修改外部函數的局部變量,而不是創建一個新的同名局部變量.并且會影響到外部函數中的同名變量.這樣可以實現在嵌套函數中共享和修改變量的目的.(如果不加nonlocal, 也是可以在嵌套函數中訪問到外層的變量的,只是無法修改)

 def outer():x = "local"def inner():nonlocal xx = "nonlocal"print(x)inner()print("outer:", x)x = 'global'outer()print('global:', x)

2. 函數的參數傳遞.

函數參數的傳遞可以分為4類:

  1. 位置參數: 調用函數時根據函數定義的參數的位置來傳遞參數.

  2. 關鍵字參數: 函數調用通過key=value的形式來傳遞參數, 可以讓函數更加的清晰, 同時也不需要強調順序.

def self_introduction(name, age, gender):print(f"你好, 我的名字叫{name}")print(f"今年{age}歲, 性別{gender}")self_introduction(name="zhangsan", age=25, gender='男')

需要注意的是: 位置參數和關鍵字參數可以混用, 但是位置參數必須在前面, 且需要匹配順序.
但是關鍵字參數之間, 不存在先后順序.

# 強制關鍵字參數.
def self_introduction(name, age, *, gender):print(f"你好, 我的名字叫{name}")print(f"今年{age}歲, 性別{gender}")self_introduction("lisi", '男', gender=25)
  1. 缺省參數: 也叫做默認參數, 用于在定義函數的時候為參數提供默認值, 調用函數時可以不傳遞該參數的值, 所有的位置參數必須出現在默認參數前, 包括函數定義和調用.
def self_introduction(name, age, come_from='中國'):print(f"你好, 我的名字叫{name}, 今年{age}歲, 我來自{come_from}")self_introduction(name="zhangsan", age=25)
  1. 不定長參數: 也叫做可變參數, 用于不確定調用的時候會傳遞多少參數.

    a. 位置傳遞: *args. 傳遞給函數的所有參數, 都會被args所接受,會根據傳進去的參數的位置組成一個元組.

    • *args允許函數接受任意數量的位置參數.
    • 它以元組的形式傳遞參數,函數內部可以使用args變量來獲取到參數.

    b. 關鍵字傳遞: **kwargs, 在參數是key=value的情況下, 所有的key-value都會被kwargs接收, 同時會將key-value組成一個字典.

    • **kwargs允許函數接收任意數量的關鍵字參數.
    • 它以字典的形式傳遞參數, 函數內部可以使用kwargs變量來引用這個字典.
def average(a, b, c):print((a + b + c) / 3)

1.通過位置傳遞不定常參數

# 通過位置傳遞不定長參數def average(*args):# print(type(args)) -> 元組# print(args) -> (1,2,3,4,5,6)print(sum(args) / len(args))average(1, 2, 3, 4, 5 ,6)

2.通過關鍵字傳遞不定長參數

def self_introduction(**kwargs):print(kwargs)# print(f"你好, 我的名字叫{name}, 今年{age}歲, 我來自{come_from}")self_introduction(name="zhangsan", age=25, come_from='北京')

3.不定長參數在Python當中的應用

def self_introduction(*args, **kw):# print(args)# print(kw)# print(type(kwargs))# print(kwargs)print(f"你好, 我的名字叫{args[0]}, 今年{kw['age']}歲, 我來自{kw['come_from']}")self_introduction("zhangsan", age=25, come_from='北京')
補充學習: 不定長參數*args和**kwargs

請看這塊代碼:

def wrapper(*args, **kwargs):# 這里直接使用args和kwargs,并沒有加上*號cache_key = (args, tuple(sorted(kwargs.items())))if cache_key in cache:return cache.get(cache_key)# 這里使用的是加上*號的*args和**argsresult = func(*args, **kwargs)cache[cache_key] = resultreturn result

注意我在上面代碼中注釋部分的內容, 現在請思考不加 * 號的不定長參數和加上 * 號的不定長參數在用法上有什么區別?

首先再次說明一下Python當中的*args和**kwargs的用法:

  1. *args

    • 作用:*args 用于將多個位置參數(非關鍵字參數)收集為一個元組
    • 語法:在函數定義中,*args 放在形參列表的最后,表示接收所有未被其他形參捕獲的位置參數
  2. **kwargs

    • 作用:**kwargs 用于將多個關鍵字參數收集為一個字典
    • 語法:在函數定義中,**kwargs 放在形參列表的最后,表示接收所有未被其他形參捕獲的關鍵字參數
  3. 結合使用 *args 和 **kwargs
    在函數定義中,*args 和 **kwargs 可以同時使用,但 *args 必須在 **kwargs 之前

在上面的代碼中:

def wrapper(*args, **kwargs):# 這里直接使用args和kwargs,并沒有加上*號cache_key = (args, tuple(sorted(kwargs.items())))if cache_key in cache:return cache.get(cache_key)# 這里使用的是加上*號的*args和**argsresult = func(*args, **kwargs)cache[cache_key] = resultreturn result

函數定義當中的形參: def wrapper(*args, **kwargs):

  • *args 和 **kwargs 的接收:
    • *args 接收所有位置參數, 存儲為元組
    • **kwargs 接收所有關鍵字參數, 存儲為字典

下面在函數體中使用不定長參數:

# 這里直接使用args和kwargs,并沒有加上*號
cache_key = (args, tuple(sorted(kwargs.items())))
print(type(args)) # tuple
print(type(kwargs)) # dict

args 和 kwargs 是作為普通變量使用的,而不是作為參數傳遞給函數. 這里的 args 是一個元組,kwargs 是一個字典,它們已經被函數定義中的 *args 和 **kwargs 收集并存儲了

如果直接打印這里的args和kwargs的類型會發現分別是tuple()和dict()

但是我們發現在函數調用中使用的是加上*號的不定長參數:

# 這里使用的是加上*號的*args和**args
result = func(*args, **kwargs)

其實, 在函數調用中,*args 和 **kwargs 用于將已有的數據結構(元組或字典)**解包** 為函數的參數

  • *args:將一個元組解包為多個位置參數
  • **kwargs:將一個字典解包為多個關鍵字參數

總結:

  • 函數定義中,*args 和 **kwargs 用于收集動態參數
  • 函數調用中,*args 和 **kwargs 用于解包已有的數據結構(元組或字典)為函數的參數

3. 值傳遞和引用傳遞

值傳遞(Pass by Value)和引用傳遞(Pass by Reference)是關于函數參數傳遞方式的兩個概念.

值傳遞是指將實際參數的值復制一份給形式參數,函數中對形式參數的修改不會影響到實際參數的值。在值傳遞中,函數中對形式參數的修改只會影響到函數內部,不會影響到函數外部。

# 值傳遞
def modify_value(x):x = 10print(x)value = 5
modify_value(value)
print(value)

引用傳遞是指將實際參數的引用(地址)傳遞給形式參數,形式參數和實際參數指向同一塊內存地址,函數中對形式參數的修改會影響到實際參數的值。在引用傳遞中,函數中對形式參數的修改會反映到函數外部.

# 引用傳遞
def modify_list(lst):lst.append(4)  # 修改參數(列表)的內容print(1, id(lst))# lst += [5] # 不會創建新對象, 所以id值不變, 注意這里不要誤解+=lst = lst + [5] # 創建了新對象print(2, id(lst))print(1, lst)my_list = [1, 2, 3]
print(3, id(my_list))
modify_list(my_list)
print(2, my_list)

補充說明:

  • 不可變對象(如字符串、元組、數字等):修改內容時會創建新的對象,id 值會改變
  • 可變對象(如列表、字典、集合等):修改內容時不會創建新的對象,id 值保持不變

需要注意的是,雖然在Python中沒有嚴格的引用傳遞機制,但是對于可變對象(如列表、字典等),它們的傳遞方式是引用傳遞,因為它們的值可以在函數內部被修改. 而對于不可變對象(如數字、字符串等),它們的傳遞方式類是值傳遞,因為函數內部對形式參數的修改不會影響到實際參數

理解值傳遞和引用傳遞的概念對于編寫和調試代碼非常重要,可以幫助我們更好地理解函數參數傳遞的機制和代碼中的行為.

# 注意比較下面兩種調用方式:
def f(x, li=[]):for i in range(x):li.append(i)print(li)# 1. 方式一
print('當參數為4')
f(4)
print('當參數為5')
# 注意哦, 這里使用的依然是之前的那個默認的li的地址
f(5)# 2. 方式二
print('當參數為4')
f(4)
print('當參數為5')
f(5, li=[4, 5]) # 這里使用的是指定的列表, 所以地址變了
補充學習: 把函數作為參數傳遞
# 當把函數作為參數傳遞.
a_list = [15, 111, 2232, 123123, 324234]# 將a_List排序, 排序的根據是數字的個位.
def sorted_by(num):num_string = str(num)[-1]return int(num_string)b_list = sorted(a_list, key=sorted_by)
print(b_list)# 改寫之前的計算器:def add(a, b):return a + bdef calc(a, b, func):return func(a, b)res = calc(6, 6, add)
print(res)

4. 匿名函數

也稱為lambda函數,是一種簡潔的函數定義方式,用于創建一次性的、簡單的函數.

匿名函數的語法形式為:lambda 參數: 表達式

匿名函數的返回值就是 表達式的結果

它由關鍵字 lambda 開頭,后跟一個或多個參數,然后是冒號 :,最后是一個表達式, 匿名函數執行表達式的計算,并返回結果.

匿名函數通常用于需要簡單函數邏輯的地方,尤其是在需要傳遞函數作為參數的情況下,可以更簡潔地定義函數,避免定義命名函數的繁瑣。但需要注意的是,匿名函數通常用于表達式較短、邏輯簡單的情況,對于復雜的函數邏輯,仍然建議使用命名函數進行定義

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

案例: numbers = [5, 2, 7, 1, 9] 對此列表排序, 根據對3取余的 結果進行排序.

# numbers = [5, 2, 7, 1, 9] 對此列表排序, 根據對3取余的 結果進行排序.
#            2  2  1  1  0
numbers = [5, 2, 7, 1, 9]a_list = sorted(numbers, key=lambda x: x % 3)
print(a_list)

改寫前面的計算器程序:

def calculator(a, b, operator):operator_dict = {'+': lambda x, y: x + y,'-': lambda x, y: x - y,'*': lambda x, y: x * y,'/': lambda x, y: x / y,}return operator_dict.get(operator)(a, b)res = calculator(6, 6, '*')
print(res)

5. python中內置的常用函數

zip()

zip: zip([iterable, …]), 將多個可迭代對象打包成元組.它返回一個可迭代的對象,該對象生成元組,每個元組包含來自每個可迭代對象的元素, 如果各個迭代器的元素個數不一致,則返回列表長度與最短的對象相同.以長的為主使用zip_longest方法

# zip
from itertools import zip_longest
numbers = [1, 2, 3, 4]
letters = ['a', 'b', 'c']
x_list = ['d', 'e']zipped = list(zip_longest(numbers, letters, x_list, fillvalue=0))
print(zipped)for item in zipped:print(item)
map()

map(): map(function, iterable):對可迭代對象中的每個元素應用指定的函數.

# map
def square(x):return x ** 2numbers = [1, 2, 3, 4, 5]# 要將numbers中的數字全部轉換為字符串.
a_list = list(map(str, numbers))
print(a_list)
squared_numbers = map(lambda x: x**2, numbers)
print(squared_numbers)
print(list(squared_numbers))
filter()

filter(): filter(function, iterable): 對可迭代對象中的元素進行過濾. 返回值為True時保存

# filter
def is_even(x):return x % 2 == 0numbers = [1, 2, 3, 4, 5]even_numbers = filter(lambda x: x % 2 != 0, numbers)print(list(even_numbers)) # [1, 3, 5]
all()

all(): all(iterable):判斷可迭代對象中的所有元素是否都為真.如果是返回 True,否則返回 False.

# all 判斷可迭代對象中的所有元素是否都為真.如果是返回 True,否則返回 False.
print(all(['a', 'b', 'c', ''])) # False
print(all([])) # True 注意哦,Python規定如果可迭代對象為空, all()的結果就是 Truenumbers = [1, 2, 3, 4, 5, -1]
# 使用 all() 函數判斷是否所有元素都大于0
sign = all(num > 0 for num in numbers)
print(sign) # False
any()

any(): any(iterable): 判斷可迭代對象中的任何一個元素是否為真(有一個為真就是真).不是則返回 False,如果有一個為 True,則返回 True.

# any
# print(any(['', 0, '', None]))
# print(any([]))
numbers = [1, 3, 5, -1]
# 使用 any() 函數判斷numbers中是否存在偶數元素
sign = any(num % 2 == 0 for num in numbers)
print(sign)

6. 函數練習

1.編寫一個函數 get_sum_of_lists,接受多個列表作為參數,并返回它們對應位置元素的和的列表 短列表缺少的用0補齊.

from itertools import zip_longest
# [1, 2, 3, 4, 5, 6]
# [6, 5, 4, 3, 2, 1]
# 拆包
def get_sum_of_lists(*args):# print(*args)zipped = list(zip_longest(*args, fillvalue=0))result = list(map(sum, zipped))return resultlst1 = [1, 2, 3, 4, 5, 6, 7, 8]
lst2 = [6, 5, 4, 3, 2, 1]
lst3 = [6, 5, 4, 3, 2, 1, 3, 6]res = get_sum_of_lists(lst1, lst2, lst3)
print(res)

2.實現一個函數 get_max_length(words),接收一個字符串列表 words,返回列表中最長的單詞的長度.

例如,對于輸入列表 [‘apple’, ‘banana’, ‘orange’, ‘watermelon’],函數應該返回 10,因為最長的單詞是 ‘watermelon’,它的長度為 10

def get_max_length(words):# len_list = list(map(len, words))len_list = [len(word) for word in words]return max(len_list)lst = ['apple', 'banana', 'orange', 'watermelon']
print(get_max_length(lst))

3.實現一個函數get_primes, 接收一個參數n, 函數功能是: 返回n以內(包含n)的所有的質數. get_primes函數體內使用lambda實現.

只能被1跟它本身整除的數. 2, 3, 4, 5 ,6 ,7 ,8 ,9, 10 每一次取余的結果都不是0, 那么它就是質數. 反之, 就不是質數.

# all, all true , false
# filter
# 5 2 3 4
# 6 2 3 4 5
def get_primes(n):primes_list = list(filter(lambda x: all(x % i != 0 for i in range(2, x)), range(2, n + 1)))return primes_listprimes = get_primes(20)
print(primes)
遇見安然遇見你,不負代碼不負卿。
謝謝老鐵的時間,咱們下篇再見~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74428.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74428.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74428.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

EasyUI數據表格中嵌入下拉框

效果 代碼 $(function () {// 標記當前正在編輯的行var editorIndex -1;var data [{code: 1,name: 1,price: 1,status: 0},{code: 2,name: 2,price: 2,status: 1}]$(#dg).datagrid({data: data,onDblClickCell:function (index, field, value) {var dg $(this);if(field ! …

【C語言】多進程/多線程

【C語言】多進程/多線程 參考鏈接多進程/多線程服務器1. 多進程服務器2. 多線程服務器 結語參考鏈接 參考鏈接 c 中文網 菜鳥 c 多進程/多線程服務器 多進程和多線程是常用的并發編程技術。它們都允許程序同時執行多個任務,提高了系統的資源利用率和程序的運行效率…

mysql 磐維(opengauss)tidb誤刪數據之高級恢復

Mysql參考: Mysql 8.0 XtraBackupMysqlbinlog 完全恢復 - 墨天輪 Mysql 8.0 XtraBackupMysqlbinlog 完全恢復[TOC]# 一、安裝mysql 8.0.19## 1.1https://www.modb.pro/db/509223MySQL 的全量備份、增量備份與 Binlog 時間點恢復_mysqlbinlog自動備份嗎-CSDN博客文章…

3. 軸指令(omron 機器自動化控制器)——>MC_SetPosition

機器自動化控制器——第三章 軸指令 11 MC_SetPosition變量?輸入變量?輸出變量?輸入輸出變量 功能說明?時序圖?重啟動運動指令?多重啟運動指令?異常 MC_SetPosition 將軸的指令當前位置和反饋當前位置變更為任意值。 指令名稱FB/FUN圖形表現ST表現MC_SetPosition當前位…

從 @SpringBootApplication 出發,深度剖析 Spring Boot 自動裝配原理

在 Spring Boot 的開發旅程中,SpringBootApplication 注解堪稱開啟便捷開發之門的鑰匙。它不僅是一個簡單的注解,更是理解 Spring Boot 自動裝配原理的重要入口。接下來,我們將以SpringBootApplication 為切入點,深入探究 Spring …

MySQL面試專題

1.什么是BufferPool? Buffer Pool基本概念 Buffer Pool:緩沖池,簡稱BP。其作用是用來緩存表數據與索引數據,減少磁盤IO操作,提升效率。 Buffer Pool由緩存數據頁(Page) 和 對緩存數據頁進行描述的控制塊 組成, 控制…

調用百度api實現語音識別(python)

該代碼實現了一個企業級的語音識別解決方案,通過調用百度語音識別API,實現實時錄音識別和對已有音頻語音識別功能。 百度智能云:請自行訪問百度智能云,開通免費的語音識別功能,獲取API_KEY和SECRET_KEY。操作按照百度流程即可,可免費申請。 首先,配置下百度API和描述下錯…

KRaft模式

目錄標題 Kraft模式**1. 什么是Kraft模式?****2. 為什么引入Kraft模式?****3. 核心優勢****4. 架構與工作原理****5. 部署與配置要點****6. 適用場景與最佳實踐****總結**KIP-833: Mark KRaft as Production Ready除了Kraft模式,Kafka還有以下…

單片機電路中常見的英文術語及縮寫

以下是單片機電路中常見的英文術語及縮寫的解釋及其作用說明,按功能分類整理,便于理解: 一、核心術語 MCU (Microcontroller Unit) ? 中文:微控制器單元 ? 作用:單片機的核心芯片,集成CPU、存儲器、外設接…

常見框架漏洞之一:Thinkphp5x

ThinkPHP是為了簡化企業級應?開發和敏捷WEB應?開發?誕?的,是?個快速、兼容?且簡單的輕量級國產PHP開發框架,誕?于2006年初,原名FCS,2007年元旦正式更名為 ThinkPHP,遵循Apache2開源協議發布,從Stru…

2025年優化算法:龍卷風優化算法(Tornado optimizer with Coriolis force,TOC)

龍卷風優化算法(Tornado optimizer with Coriolis force)是發表在中科院二區期刊“ARTIFICIAL INTELLIGENCE REVIEW”(IF:11.7)的2025年智能優化算法 01.引言 當自然界的狂暴之力,化身數字世界的智慧引擎&…

面試中如何回答性能優化的問題

性能問題和Bug不同,后者的分析和解決思路更清晰,很多時候從應用日志(文中的應用指分布式服務下的單個節點)即可直接找到問題根源,而性能問題,其排查思路更為復雜一些。 對應用進行性能優化,是一個系統性的工程,對工程師的技術廣度和技術深度都有所要求。一個簡單的應用…

CMake 函數和宏

CMake 函數 CMake 函數定義語法如下, 其中 name 為函數名, <arg1> 為參數名, <commands> 為函數體. 函數定義后, 可以通過 name 調用函數. 函數名允許字母數字下劃線, 不區分大小寫. function(name [<arg1> ...])<commands> endfunction()如下的樣例…

【QA】Qt有哪些迭代器模式的應用?

在 Qt/C 中&#xff0c;迭代器模式的設計主要分為 標準 C 風格 和 Qt 框架特有風格&#xff0c;以下結合代碼詳細說明兩種實現方式的關鍵設計及其應用場景&#xff1a; 一、Qt 框架中的迭代器模式設計 Qt 提供了兩種迭代器風格&#xff1a;Java 風格&#xff08;顯式迭代器&am…

Mysql表的簡單操作

&#x1f3dd;?專欄&#xff1a;Mysql_貓咪-9527的博客-CSDN博客 &#x1f305;主頁&#xff1a;貓咪-9527-CSDN博客 “欲窮千里目&#xff0c;更上一層樓。會當凌絕頂&#xff0c;一覽眾山小。” 目錄 3.1 創建表 3.2 查看表結構 3.3 修改表 1. 添加字段 2. 修改字段 3…

【云馨AI-大模型】自動化部署Dify 1.1.2,無需科學上網,Linux環境輕松實現,附Docker離線安裝等

Dify介紹 官網&#xff1a;https://dify.ai/zh生成式 AI 應用創新引擎開源的 LLM 應用開發平臺。提供從 Agent 構建到 AI workflow 編排、RAG 檢索、模型管理等能力&#xff0c;輕松構建和運營生成式 AI 原生應用。 Dify安裝腳本 目錄創建 mkdir -p /data/yunxinai &&a…

WordPress上傳圖片時顯示“未提供數據”錯誤

在WordPress中上傳圖片時顯示“未提供數據”的錯誤&#xff0c;通常是由多種原因引起的&#xff0c;以下是一些常見的問題及其解決方法&#xff1a; 1. 文件權限問題 WordPress需要正確的文件和目錄權限才能正常上傳圖片。如果權限設置不正確&#xff0c;可能會導致無法上傳圖…

python3面試題20個(python web篇)

更多內容請見: python3案例和總結-專欄介紹和目錄 文章目錄 1.python asyncio的原理?2.對Flask藍圖(Blueprint)的理解?3.Flask 和 Django 路由映射的區別?4.什么是wsgi,uwsgi,uWSGI?5.Django、Flask、Tornado的對比?6.CORS 和 CSRF的區別?7.Session,Cookie,JWT的理解8.簡…

RedisTemplate和RedissonClient適用的場景有什么不同

在 Spring Boot 項目中&#xff0c;RedisTemplate 和 RedissonClient 分別針對不同的使用場景設計&#xff0c;以下是它們的核心區別和適用場景分析&#xff1a; 一、RedisTemplate&#xff08;Spring Data Redis&#xff09; 定位 Spring 官方提供的 Redis 操作工具&#xf…

人臉表情識別系統分享(基于深度學習+OpenCV+PyQt5)

最近終于把畢業大論文忙完了&#xff0c;眾所周知碩士大論文需要有三個工作點&#xff0c;表情識別領域的第三個工作點一般是做一個表情識別系統出來&#xff0c;如下圖所示。 這里分享一下這個表情識別系統&#xff1a; 采用 深度學習OpenCVPyQt5 構建&#xff0c;主要功能包…