Python 函數(shù)定義以及參數(shù)傳遞
創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、成都做網(wǎng)站、貢井網(wǎng)絡(luò)推廣、小程序設(shè)計、貢井網(wǎng)絡(luò)營銷、貢井企業(yè)策劃、貢井品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供貢井建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:m.kartarina.com
1.函數(shù)定義
#形如def func(args...):
doSomething123
以關(guān)鍵字def 開頭,后面是函數(shù)名和參數(shù)下面是函數(shù)處理過程。
舉例:
def add( a, b ):
return a+b12
參數(shù)可以設(shè)定默認(rèn)值,如:
def add( a, b=10 ): #注意:默認(rèn)值參數(shù)只會運算一次
return a+b12
默認(rèn)值參數(shù)只會運算一次是什么意思?
def func( a, b=[] ): #b的默認(rèn)值指向一個空的列表,每次不帶默認(rèn)值都會指向這塊內(nèi)存
b.append(a) return b
print(func(1))#向默認(rèn)的空列表里加入元素1 ,默認(rèn)列表里已經(jīng)是[1]print(func(2))#向默認(rèn)的列表里加入元素2,默認(rèn)列表里已經(jīng)是[1,2]print(func(3,[]))#向b指向的空列表里加入元素1 ,默認(rèn)列表里還是[1,2]print(func(4))#向默認(rèn)的列表里加入元素4,默認(rèn)列表里已經(jīng)是[1,2,4]'''
結(jié)果:
[1]
[1, 2]
[3]
[1, 2, 4]
'''12345678910111213141516
這下明白為什么默認(rèn)參數(shù)只計算一次了吧,函數(shù)參數(shù)不傳遞時默認(rèn)值總是指向固定的內(nèi)存空間,就是第一次計算的空間。
2.參數(shù)傳遞
def func(a, b):
print('a=%d, b=%d' % (a,b) )12
在使用函數(shù)時可以如下方式,結(jié)果都是相同的
func(10,20) #不使用參數(shù)名,需要按參數(shù)順序傳遞func(a=10,b=20) #使用參數(shù)名可以不按順序傳遞func(b=20,a=10)#結(jié)果:a=10, b=20a=10, b=20a=10, b=201234567
如果函數(shù)定義形式如下方式:
def func(*args): #這種定義會把傳遞的參數(shù)包成元組
print(args,type(args))
func(10,20)#結(jié)果:#(10, 20) class 'tuple'1234567
舉一個和上述過程相反的例子:
def func(a,b):
print('a=%d, b=%d' % (a,b) )
a = (10, 20)
func(*a) #在調(diào)用函數(shù)使用`*`則會把元組解包成單個變量按順序傳入函數(shù)#結(jié)果:a=10, b=20123456
總結(jié):*號在定義函數(shù)參數(shù)時,傳入函數(shù)的參數(shù)會轉(zhuǎn)換成元組,如果 *號在調(diào)用時則會把元組解包成單個元素。
另一種定義:
def func(**kw):#使用**定義參數(shù)會把傳入?yún)?shù)包裝成字典dict
print(kw, type(kw) )
func(a=10,b=20)#這種函數(shù)在使用時必須指定參數(shù)值,使用key=value這種形式#結(jié)果:{'b': 20, 'a': 10} class 'dict'12345
相反的例子:
def func(a,b):
print('a=%d, b=%d' % (a,b) )
d = {'a':10, 'b':20 }
func(**d) #在調(diào)用時使用**會把字典解包成變量傳入函數(shù)。12345
def func(*args, **kw):#這種形式的定義代表可以接受任意類型的參數(shù)
print(args,kw )12
總結(jié):**號在定義函數(shù)參數(shù)時,傳入函數(shù)的參數(shù)會轉(zhuǎn)換成字典,如果 **號在調(diào)用時則會把字典解包成單個元素。
lambda表達(dá)式
lambda表達(dá)式就是一種簡單的函數(shù)
形如 f = lambda 參數(shù)1,參數(shù)2: 返回的計算值
例如:
add = lambda x,y: x+y
print(add(1,2))'''
結(jié)果:3
'''12345
python 的函數(shù)參數(shù)類型分為4種:
1.位置參數(shù):調(diào)用函數(shù)時根據(jù)函數(shù)定義的參數(shù)位置來傳遞參數(shù),位置參數(shù)也可以叫做必要參數(shù),函數(shù)調(diào)用時必須要傳的參數(shù)。
當(dāng)參數(shù)滿足函數(shù)必要參數(shù)傳參的條件,函數(shù)能夠正常執(zhí)行:
add(1,2) #兩個參數(shù)的順序必須一一對應(yīng),且少一個參數(shù)都不可以
當(dāng)我們運行上面的程序,輸出:
當(dāng)函數(shù)需要兩個必要參數(shù),但是調(diào)用函數(shù)只給了一個參數(shù)時,程序會拋出異常
add(1)
當(dāng)我們運行上面的程序,輸出:
當(dāng)函數(shù)需要兩個必要參數(shù),但是調(diào)用函數(shù)只給了三個參數(shù)時,程序會拋出異常
add(1,2,3)
當(dāng)我們運行上面的程序,輸出
2.關(guān)鍵字參數(shù):用于函數(shù)調(diào)用,通過“鍵-值”形式加以指定。可以讓函數(shù)更加清晰、容易使用,同時也清除了參數(shù)的順序需求。
add(1,2) # 這種方式傳參,必須按順序傳參:x對應(yīng)1,y對應(yīng):2
add(y=2,x=1) #以關(guān)健字方式傳入?yún)?shù)(可以不按順序)
正確的調(diào)用方式
add(x=1, y=2)
add(y=2, x=1)
add(1, y=2)
以上調(diào)用方式都是允許的,能夠正常執(zhí)行
錯誤的調(diào)用方式
add(x=1, 2)
add(y=2, 1)
以上調(diào)用都會拋出SyntaxError 異常
上面例子可以看出:有位置參數(shù)時,位置參數(shù)必須在關(guān)鍵字參數(shù)的前面,但關(guān)鍵字參數(shù)之間不存在先后順序的
3.默認(rèn)參數(shù):用于定義函數(shù),為參數(shù)提供默認(rèn)值,調(diào)用函數(shù)時可傳可不傳該默認(rèn)參數(shù)的值,所有位置參數(shù)必須出現(xiàn)在默認(rèn)參數(shù)前,包括函數(shù)定義和調(diào)用,有多個默認(rèn)參數(shù)時,調(diào)用的時候,既可以按順序提供默認(rèn)參數(shù),也可以不按順序提供部分默認(rèn)參數(shù)。當(dāng)不按順序提供部分默認(rèn)參數(shù)時,需要把參數(shù)名寫上
默認(rèn)參數(shù)的函數(shù)定義
上面示例第一個是正確的定義位置參數(shù)的方式,第二個是錯誤的,因為位置參數(shù)在前,默認(rèn)參數(shù)在后
def add1(x=1,y) 的定義會拋出如下異常
默認(rèn)參數(shù)的函數(shù)調(diào)用
注意:定義默認(rèn)參數(shù)默認(rèn)參數(shù)最好不要定義為可變對象,容易掉坑
不可變對象:該對象所指向的內(nèi)存中的值不能被改變,int,string,float,tuple
可變對象,該對象所指向的內(nèi)存中的值可以被改變,dict,list
這里只要理解一下這個概念就行或者自行百度,后續(xù)會寫相關(guān)的專題文章講解
舉一個簡單示例
4.可變參數(shù)區(qū)別:定義函數(shù)時,有時候我們不確定調(diào)用的時候會多少個參數(shù),j就可以使用可變參數(shù)
可變參數(shù)主要有兩類:
*args: (positional argument) 允許任意數(shù)量的可選位置參數(shù)(參數(shù)),將被分配給一個元組, 參數(shù)名前帶*,args只是約定俗成的變量名,可以替換其他名稱
**kwargs:(keyword argument) 允許任意數(shù)量的可選關(guān)鍵字參數(shù),,將被分配給一個字典,參數(shù)名前帶**,kwargs只是約定俗成的變量名,可以替換其他名稱
*args 的用法
args 是用來傳遞一個非鍵值對的可變數(shù)量的參數(shù)列表給函數(shù)
語法是使用 符號的數(shù)量可變的參數(shù); 按照慣例,通常是使用arg這個單詞,args相當(dāng)于一個變量名,可以自己定義的
在上面的程序中,我們使用* args作為一個可變長度參數(shù)列表傳遞給add()函數(shù)。 在函數(shù)中,我們有一個循環(huán)實現(xiàn)傳遞的參數(shù)計算和輸出結(jié)果。
還可以直接傳遞列表或者數(shù)組的方式傳遞參數(shù),以數(shù)組或者列表方式傳遞參數(shù)名前面加(*) 號
理解* * kwargs
**kwargs 允許你將不定長度的鍵值對, 作為參數(shù)傳遞給函數(shù),這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動組裝為一個dict
下篇詳細(xì)講解 *args, **kwargs 的參數(shù)傳遞和使用敬請關(guān)注
【常見的內(nèi)置函數(shù)】
1、enumerate(iterable,start=0)
是python的內(nèi)置函數(shù),是枚舉、列舉的意思,對于一個可迭代的(iterable)/可遍歷的對象(如列表、字符串),enumerate將其組成一個索引序列,利用它可以同時獲得索引和值。
2、zip(*iterables,strict=False)
用于將可迭代的對象作為參數(shù),將對象中對應(yīng)的元素打包成一個個元組,然后返回由這些元組組成的列表。如果各個迭代器的元素個數(shù)不一致,則返回列表長度與最短的對象相同,利用*號操作符,可以將元組解壓為列表。
3、filter(function,iterable)
filter是將一個序列進(jìn)行過濾,返回迭代器的對象,去除不滿足條件的序列。
4、isinstance(object,classinfo)
是用來判斷某一個變量或者是對象是不是屬于某種類型的一個函數(shù),如果參數(shù)object是classinfo的實例,或者object是classinfo類的子類的一個實例,
返回True。如果object不是一個給定類型的的對象, 則返回結(jié)果總是False
5、eval(expression[,globals[,locals]])
用來將字符串str當(dāng)成有效的表達(dá)式來求值并返回計算結(jié)果,表達(dá)式解析參數(shù)expression并作為Python表達(dá)式進(jìn)行求值(從技術(shù)上說是一個條件列表),采用globals和locals字典作為全局和局部命名空間。
【常用的句式】
1、format字符串格式化
format把字符串當(dāng)成一個模板,通過傳入的參數(shù)進(jìn)行格式化,非常實用且強大。
2、連接字符串
常使用+連接兩個字符串。
3、if...else條件語句
Python條件語句是通過一條或多條語句的執(zhí)行結(jié)果(True或者False)來決定執(zhí)行的代碼塊。其中if...else語句用來執(zhí)行需要判斷的情形。
4、for...in、while循環(huán)語句
循環(huán)語句就是遍歷一個序列,循環(huán)去執(zhí)行某個操作,Python中的循環(huán)語句有for和while。
5、import導(dǎo)入其他腳本的功能
有時需要使用另一個python文件中的腳本,這其實很簡單,就像使用import關(guān)鍵字導(dǎo)入任何模塊一樣。
從零開始用Python構(gòu)建神經(jīng)網(wǎng)絡(luò)
動機:為了更加深入的理解深度學(xué)習(xí),我們將使用 python 語言從頭搭建一個神經(jīng)網(wǎng)絡(luò),而不是使用像 Tensorflow 那樣的封裝好的框架。我認(rèn)為理解神經(jīng)網(wǎng)絡(luò)的內(nèi)部工作原理,對數(shù)據(jù)科學(xué)家來說至關(guān)重要。
這篇文章的內(nèi)容是我的所學(xué),希望也能對你有所幫助。
神經(jīng)網(wǎng)絡(luò)是什么?
介紹神經(jīng)網(wǎng)絡(luò)的文章大多數(shù)都會將它和大腦進(jìn)行類比。如果你沒有深入研究過大腦與神經(jīng)網(wǎng)絡(luò)的類比,那么將神經(jīng)網(wǎng)絡(luò)解釋為一種將給定輸入映射為期望輸出的數(shù)學(xué)關(guān)系會更容易理解。
神經(jīng)網(wǎng)絡(luò)包括以下組成部分
? 一個輸入層,x
? 任意數(shù)量的隱藏層
? 一個輸出層,?
? 每層之間有一組權(quán)值和偏置,W and b
? 為隱藏層選擇一種激活函數(shù),σ。在教程中我們使用 Sigmoid 激活函數(shù)
下圖展示了 2 層神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)(注意:我們在計算網(wǎng)絡(luò)層數(shù)時通常排除輸入層)
2 層神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)
用 Python 可以很容易的構(gòu)建神經(jīng)網(wǎng)絡(luò)類
訓(xùn)練神經(jīng)網(wǎng)絡(luò)
這個網(wǎng)絡(luò)的輸出 ? 為:
你可能會注意到,在上面的等式中,輸出 ? 是 W 和 b 函數(shù)。
因此 W 和 b 的值影響預(yù)測的準(zhǔn)確率. 所以根據(jù)輸入數(shù)據(jù)對 W 和 b 調(diào)優(yōu)的過程就被成為訓(xùn)練神經(jīng)網(wǎng)絡(luò)。
每步訓(xùn)練迭代包含以下兩個部分:
? 計算預(yù)測結(jié)果 ?,這一步稱為前向傳播
? 更新 W 和 b,,這一步成為反向傳播
下面的順序圖展示了這個過程:
前向傳播
正如我們在上圖中看到的,前向傳播只是簡單的計算。對于一個基本的 2 層網(wǎng)絡(luò)來說,它的輸出是這樣的:
我們在 NeuralNetwork 類中增加一個計算前向傳播的函數(shù)。為了簡單起見我們假設(shè)偏置 b 為0:
但是我們還需要一個方法來評估預(yù)測結(jié)果的好壞(即預(yù)測值和真實值的誤差)。這就要用到損失函數(shù)。
損失函數(shù)
常用的損失函數(shù)有很多種,根據(jù)模型的需求來選擇。在本教程中,我們使用誤差平方和作為損失函數(shù)。
誤差平方和是求每個預(yù)測值和真實值之間的誤差再求和,這個誤差是他們的差值求平方以便我們觀察誤差的絕對值。
訓(xùn)練的目標(biāo)是找到一組 W 和 b,使得損失函數(shù)最好小,也即預(yù)測值和真實值之間的距離最小。
反向傳播
我們已經(jīng)度量出了預(yù)測的誤差(損失),現(xiàn)在需要找到一種方法來傳播誤差,并以此更新權(quán)值和偏置。
為了知道如何適當(dāng)?shù)恼{(diào)整權(quán)值和偏置,我們需要知道損失函數(shù)對權(quán)值 W 和偏置 b 的導(dǎo)數(shù)。
回想微積分中的概念,函數(shù)的導(dǎo)數(shù)就是函數(shù)的斜率。
梯度下降法
如果我們已經(jīng)求出了導(dǎo)數(shù),我們就可以通過增加或減少導(dǎo)數(shù)值來更新權(quán)值 W 和偏置 b(參考上圖)。這種方式被稱為梯度下降法。
但是我們不能直接計算損失函數(shù)對權(quán)值和偏置的導(dǎo)數(shù),因為在損失函數(shù)的等式中并沒有顯式的包含他們。因此,我們需要運用鏈?zhǔn)角髮?dǎo)發(fā)在來幫助計算導(dǎo)數(shù)。
鏈?zhǔn)椒▌t用于計算損失函數(shù)對 W 和 b 的導(dǎo)數(shù)。注意,為了簡單起見。我們只展示了假設(shè)網(wǎng)絡(luò)只有 1 層的偏導(dǎo)數(shù)。
這雖然很簡陋,但是我們依然能得到想要的結(jié)果—損失函數(shù)對權(quán)值 W 的導(dǎo)數(shù)(斜率),因此我們可以相應(yīng)的調(diào)整權(quán)值。
現(xiàn)在我們將反向傳播算法的函數(shù)添加到 Python 代碼中
為了更深入的理解微積分原理和反向傳播中的鏈?zhǔn)角髮?dǎo)法則,我強烈推薦 3Blue1Brown 的如下教程:
Youtube:
整合并完成一個實例
既然我們已經(jīng)有了包括前向傳播和反向傳播的完整 Python 代碼,那么就將其應(yīng)用到一個例子上看看它是如何工作的吧。
神經(jīng)網(wǎng)絡(luò)可以通過學(xué)習(xí)得到函數(shù)的權(quán)重。而我們僅靠觀察是不太可能得到函數(shù)的權(quán)重的。
讓我們訓(xùn)練神經(jīng)網(wǎng)絡(luò)進(jìn)行 1500 次迭代,看看會發(fā)生什么。 注意觀察下面每次迭代的損失函數(shù),我們可以清楚地看到損失函數(shù)單調(diào)遞減到最小值。這與我們之前介紹的梯度下降法一致。
讓我們看看經(jīng)過 1500 次迭代后的神經(jīng)網(wǎng)絡(luò)的最終預(yù)測結(jié)果:
經(jīng)過 1500 次迭代訓(xùn)練后的預(yù)測結(jié)果
我們成功了!我們應(yīng)用前向和方向傳播算法成功的訓(xùn)練了神經(jīng)網(wǎng)絡(luò)并且預(yù)測結(jié)果收斂于真實值。
注意預(yù)測值和真實值之間存在細(xì)微的誤差是允許的。這樣可以防止模型過擬合并且使得神經(jīng)網(wǎng)絡(luò)對于未知數(shù)據(jù)有著更強的泛化能力。
下一步是什么?
幸運的是我們的學(xué)習(xí)之旅還沒有結(jié)束,仍然有很多關(guān)于神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)的內(nèi)容需要學(xué)習(xí)。例如:
? 除了 Sigmoid 以外,還可以用哪些激活函數(shù)
? 在訓(xùn)練網(wǎng)絡(luò)的時候應(yīng)用學(xué)習(xí)率
? 在面對圖像分類任務(wù)的時候使用卷積神經(jīng)網(wǎng)絡(luò)
我很快會寫更多關(guān)于這個主題的內(nèi)容,敬請期待!
最后的想法
我自己也從零開始寫了很多神經(jīng)網(wǎng)絡(luò)的代碼
雖然可以使用諸如 Tensorflow 和 Keras 這樣的深度學(xué)習(xí)框架方便的搭建深層網(wǎng)絡(luò)而不需要完全理解其內(nèi)部工作原理。但是我覺得對于有追求的數(shù)據(jù)科學(xué)家來說,理解內(nèi)部原理是非常有益的。
這種練習(xí)對我自己來說已成成為重要的時間投入,希望也能對你有所幫助
1、函數(shù)定義
①使用def關(guān)鍵字定義函數(shù)
②
def 函數(shù)名(參數(shù)1.參數(shù)2.參數(shù)3...):
"""文檔字符串,docstring,用來說明函數(shù)的作用"""
#函數(shù)體
return 表達(dá)式
注釋的作用:說明函數(shù)是做什么的,函數(shù)有什么功能。
③遇到冒號要縮進(jìn),冒號后面所有的縮進(jìn)的代碼塊構(gòu)成了函數(shù)體,描述了函數(shù)是做什么的,即函數(shù)的功能是什么。Python函數(shù)的本質(zhì)與數(shù)學(xué)中的函數(shù)的本質(zhì)是一致的。
2、函數(shù)調(diào)用
①函數(shù)必須先定義,才能調(diào)用,否則會報錯。
②無參數(shù)時函數(shù)的調(diào)用:函數(shù)名(),有參數(shù)時函數(shù)的調(diào)用:函數(shù)名(參數(shù)1.參數(shù)2.……)
③不要在定義函數(shù)的時候在函數(shù)體里面調(diào)用本身,否則會出不來,陷入循環(huán)調(diào)用。
④函數(shù)需要調(diào)用函數(shù)體才會被執(zhí)行,單純的只是定義函數(shù)是不會被執(zhí)行的。
⑤Debug工具中Step into進(jìn)入到調(diào)用的函數(shù)里,Step Into My Code進(jìn)入到調(diào)用的模塊里函數(shù)。
網(wǎng)站題目:Python函數(shù)泛化,python 泛型
轉(zhuǎn)載來源:http://m.kartarina.com/article46/hddieg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計、企業(yè)建站、網(wǎng)站策劃、企業(yè)網(wǎng)站制作、商城網(wǎng)站、品牌網(wǎng)站設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)