Python 函數(shù)
10年積累的網(wǎng)站設(shè)計(jì)、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有西陵免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
函數(shù)是組織好的,可重復(fù)使用的,用來(lái)實(shí)現(xiàn)單一,或相關(guān)聯(lián)功能的代碼段。
函數(shù)能提高應(yīng)用的模塊性,和代碼的重復(fù)利用率。你已經(jīng)知道Python提供了許多內(nèi)建函數(shù),比如print()。但你也可以自己創(chuàng)建函數(shù),這被叫做用戶(hù)自定義函數(shù)。
定義一個(gè)函數(shù)
你可以定義一個(gè)由自己想要功能的函數(shù),以下是簡(jiǎn)單的規(guī)則:
函數(shù)代碼塊以?def?關(guān)鍵詞開(kāi)頭,后接函數(shù)標(biāo)識(shí)符名稱(chēng)和圓括號(hào)()。
任何傳入?yún)?shù)和自變量必須放在圓括號(hào)中間。圓括號(hào)之間可以用于定義參數(shù)。
函數(shù)的第一行語(yǔ)句可以選擇性地使用文檔字符串—用于存放函數(shù)說(shuō)明。
函數(shù)內(nèi)容以冒號(hào)起始,并且縮進(jìn)。
return [表達(dá)式]?結(jié)束函數(shù),選擇性地返回一個(gè)值給調(diào)用方。不帶表達(dá)式的return相當(dāng)于返回 None。
語(yǔ)法
def functionname( parameters ): ? "函數(shù)_文檔字符串"
function_suite
return [expression]
默認(rèn)情況下,參數(shù)值和參數(shù)名稱(chēng)是按函數(shù)聲明中定義的順序匹配起來(lái)的。
實(shí)例
以下為一個(gè)簡(jiǎn)單的Python函數(shù),它將一個(gè)字符串作為傳入?yún)?shù),再打印到標(biāo)準(zhǔn)顯示設(shè)備上。
實(shí)例(Python 2.0+)
def printme( str ): ? "打印傳入的字符串到標(biāo)準(zhǔn)顯示設(shè)備上"
print str
return
函數(shù)調(diào)用
定義一個(gè)函數(shù)只給了函數(shù)一個(gè)名稱(chēng),指定了函數(shù)里包含的參數(shù),和代碼塊結(jié)構(gòu)。
這個(gè)函數(shù)的基本結(jié)構(gòu)完成以后,你可以通過(guò)另一個(gè)函數(shù)調(diào)用執(zhí)行,也可以直接從Python提示符執(zhí)行。
如下實(shí)例調(diào)用了printme()函數(shù):
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 定義函數(shù)def printme( str ): ? "打印任何傳入的字符串"
print str
return
# 調(diào)用函數(shù)printme("我要調(diào)用用戶(hù)自定義函數(shù)!")printme("再次調(diào)用同一函數(shù)")
以上實(shí)例輸出結(jié)果:
我要調(diào)用用戶(hù)自定義函數(shù)!再次調(diào)用同一函數(shù)
參數(shù)傳遞
在 python 中,類(lèi)型屬于對(duì)象,變量是沒(méi)有類(lèi)型的:
a=[1,2,3]
a="Runoob"
以上代碼中,[1,2,3]?是 List 類(lèi)型,"Runoob"?是 String 類(lèi)型,而變量 a 是沒(méi)有類(lèi)型,她僅僅是一個(gè)對(duì)象的引用(一個(gè)指針),可以是 List 類(lèi)型對(duì)象,也可以指向 String 類(lèi)型對(duì)象。
可更改(mutable)與不可更改(immutable)對(duì)象
在 python 中,strings, tuples, 和 numbers 是不可更改的對(duì)象,而 list,dict 等則是可以修改的對(duì)象。
不可變類(lèi)型:變量賦值?a=5?后再賦值?a=10,這里實(shí)際是新生成一個(gè) int 值對(duì)象 10,再讓 a 指向它,而 5 被丟棄,不是改變a的值,相當(dāng)于新生成了a。
可變類(lèi)型:變量賦值?la=[1,2,3,4]?后再賦值?la[2]=5?則是將 list la 的第三個(gè)元素值更改,本身la沒(méi)有動(dòng),只是其內(nèi)部的一部分值被修改了。
python 函數(shù)的參數(shù)傳遞:
不可變類(lèi)型:類(lèi)似 c++ 的值傳遞,如 整數(shù)、字符串、元組。如fun(a),傳遞的只是a的值,沒(méi)有影響a對(duì)象本身。比如在 fun(a)內(nèi)部修改 a 的值,只是修改另一個(gè)復(fù)制的對(duì)象,不會(huì)影響 a 本身。
可變類(lèi)型:類(lèi)似 c++ 的引用傳遞,如 列表,字典。如 fun(la),則是將 la 真正的傳過(guò)去,修改后fun外部的la也會(huì)受影響
python 中一切都是對(duì)象,嚴(yán)格意義我們不能說(shuō)值傳遞還是引用傳遞,我們應(yīng)該說(shuō)傳不可變對(duì)象和傳可變對(duì)象。
python 傳不可變對(duì)象實(shí)例
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
def ChangeInt( a ): ? ?a = 10
b = 2ChangeInt(b)print b # 結(jié)果是 2
實(shí)例中有 int 對(duì)象 2,指向它的變量是 b,在傳遞給 ChangeInt 函數(shù)時(shí),按傳值的方式復(fù)制了變量 b,a 和 b 都指向了同一個(gè) Int 對(duì)象,在 a=10 時(shí),則新生成一個(gè) int 值對(duì)象 10,并讓 a 指向它。
傳可變對(duì)象實(shí)例
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 可寫(xiě)函數(shù)說(shuō)明def changeme( mylist ): ? "修改傳入的列表"
mylist.append([1,2,3,4])
print "函數(shù)內(nèi)取值: ", mylist
return
# 調(diào)用changeme函數(shù)mylist = [10,20,30]changeme( mylist )print "函數(shù)外取值: ", mylist
實(shí)例中傳入函數(shù)的和在末尾添加新內(nèi)容的對(duì)象用的是同一個(gè)引用,故輸出結(jié)果如下:
函數(shù)內(nèi)取值: ?[10, 20, 30, [1, 2, 3, 4]]函數(shù)外取值: ?[10, 20, 30, [1, 2, 3, 4]]
參數(shù)
以下是調(diào)用函數(shù)時(shí)可使用的正式參數(shù)類(lèi)型:
必備參數(shù)
關(guān)鍵字參數(shù)
默認(rèn)參數(shù)
不定長(zhǎng)參數(shù)
必備參數(shù)
必備參數(shù)須以正確的順序傳入函數(shù)。調(diào)用時(shí)的數(shù)量必須和聲明時(shí)的一樣。
調(diào)用printme()函數(shù),你必須傳入一個(gè)參數(shù),不然會(huì)出現(xiàn)語(yǔ)法錯(cuò)誤:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
#可寫(xiě)函數(shù)說(shuō)明def printme( str ): ? "打印任何傳入的字符串"
print str
return
#調(diào)用printme函數(shù)printme()
以上實(shí)例輸出結(jié)果:
Traceback (most recent call last):
File "test.py", line 11, in module
printme()TypeError: printme() takes exactly 1 argument (0 given)
關(guān)鍵字參數(shù)
關(guān)鍵字參數(shù)和函數(shù)調(diào)用關(guān)系緊密,函數(shù)調(diào)用使用關(guān)鍵字參數(shù)來(lái)確定傳入的參數(shù)值。
使用關(guān)鍵字參數(shù)允許函數(shù)調(diào)用時(shí)參數(shù)的順序與聲明時(shí)不一致,因?yàn)?Python 解釋器能夠用參數(shù)名匹配參數(shù)值。
以下實(shí)例在函數(shù) printme() 調(diào)用時(shí)使用參數(shù)名:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
#可寫(xiě)函數(shù)說(shuō)明def printme( str ): ? "打印任何傳入的字符串"
print str
return
#調(diào)用printme函數(shù)printme( str = "My string")
以上實(shí)例輸出結(jié)果:
My string
下例能將關(guān)鍵字參數(shù)順序不重要展示得更清楚:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
#可寫(xiě)函數(shù)說(shuō)明def printinfo( name, age ): ? "打印任何傳入的字符串"
print "Name: ", name
print "Age ", age
return
#調(diào)用printinfo函數(shù)printinfo( age=50, name="miki" )
以上實(shí)例輸出結(jié)果:
Name: ?mikiAge ?50
默認(rèn)參數(shù)
調(diào)用函數(shù)時(shí),默認(rèn)參數(shù)的值如果沒(méi)有傳入,則被認(rèn)為是默認(rèn)值。下例會(huì)打印默認(rèn)的age,如果age沒(méi)有被傳入:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
#可寫(xiě)函數(shù)說(shuō)明def printinfo( name, age = 35 ): ? "打印任何傳入的字符串"
print "Name: ", name
print "Age ", age
return
#調(diào)用printinfo函數(shù)printinfo( age=50, name="miki" )printinfo( name="miki" )
以上實(shí)例輸出結(jié)果:
Name: ?mikiAge ?50Name: ?mikiAge ?35
不定長(zhǎng)參數(shù)
你可能需要一個(gè)函數(shù)能處理比當(dāng)初聲明時(shí)更多的參數(shù)。這些參數(shù)叫做不定長(zhǎng)參數(shù),和上述2種參數(shù)不同,聲明時(shí)不會(huì)命名?;菊Z(yǔ)法如下:
def functionname([formal_args,] *var_args_tuple ): ? "函數(shù)_文檔字符串"
function_suite
return [expression]
加了星號(hào)(*)的變量名會(huì)存放所有未命名的變量參數(shù)。不定長(zhǎng)參數(shù)實(shí)例如下:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 可寫(xiě)函數(shù)說(shuō)明def printinfo( arg1, *vartuple ): ? "打印任何傳入的參數(shù)"
print "輸出: "
print arg1
for var in vartuple: ? ? ?print var
return
# 調(diào)用printinfo 函數(shù)printinfo( 10 )printinfo( 70, 60, 50 )
以上實(shí)例輸出結(jié)果:
輸出:10輸出:706050
匿名函數(shù)
python 使用 lambda 來(lái)創(chuàng)建匿名函數(shù)。
lambda只是一個(gè)表達(dá)式,函數(shù)體比def簡(jiǎn)單很多。
lambda的主體是一個(gè)表達(dá)式,而不是一個(gè)代碼塊。僅僅能在lambda表達(dá)式中封裝有限的邏輯進(jìn)去。
lambda函數(shù)擁有自己的命名空間,且不能訪(fǎng)問(wèn)自有參數(shù)列表之外或全局命名空間里的參數(shù)。
雖然lambda函數(shù)看起來(lái)只能寫(xiě)一行,卻不等同于C或C++的內(nèi)聯(lián)函數(shù),后者的目的是調(diào)用小函數(shù)時(shí)不占用棧內(nèi)存從而增加運(yùn)行效率。
語(yǔ)法
lambda函數(shù)的語(yǔ)法只包含一個(gè)語(yǔ)句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
如下實(shí)例:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 可寫(xiě)函數(shù)說(shuō)明sum = lambda arg1, arg2: arg1 + arg2
# 調(diào)用sum函數(shù)print "相加后的值為 : ", sum( 10, 20 )print "相加后的值為 : ", sum( 20, 20 )
以上實(shí)例輸出結(jié)果:
相加后的值為 : ?30相加后的值為 : ?40
return 語(yǔ)句
return語(yǔ)句[表達(dá)式]退出函數(shù),選擇性地向調(diào)用方返回一個(gè)表達(dá)式。不帶參數(shù)值的return語(yǔ)句返回None。之前的例子都沒(méi)有示范如何返回?cái)?shù)值,下例便告訴你怎么做:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 可寫(xiě)函數(shù)說(shuō)明def sum( arg1, arg2 ): ? # 返回2個(gè)參數(shù)的和."
total = arg1 + arg2
print "函數(shù)內(nèi) : ", total
return total
# 調(diào)用sum函數(shù)total = sum( 10, 20 )
以上實(shí)例輸出結(jié)果:
函數(shù)內(nèi) : ?30
變量作用域
一個(gè)程序的所有的變量并不是在哪個(gè)位置都可以訪(fǎng)問(wèn)的。訪(fǎng)問(wèn)權(quán)限決定于這個(gè)變量是在哪里賦值的。
變量的作用域決定了在哪一部分程序你可以訪(fǎng)問(wèn)哪個(gè)特定的變量名稱(chēng)。兩種最基本的變量作用域如下:
全局變量
局部變量
全局變量和局部變量
定義在函數(shù)內(nèi)部的變量擁有一個(gè)局部作用域,定義在函數(shù)外的擁有全局作用域。
局部變量只能在其被聲明的函數(shù)內(nèi)部訪(fǎng)問(wèn),而全局變量可以在整個(gè)程序范圍內(nèi)訪(fǎng)問(wèn)。調(diào)用函數(shù)時(shí),所有在函數(shù)內(nèi)聲明的變量名稱(chēng)都將被加入到作用域中。如下實(shí)例:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
total = 0 # 這是一個(gè)全局變量# 可寫(xiě)函數(shù)說(shuō)明def sum( arg1, arg2 ): ? #返回2個(gè)參數(shù)的和."
total = arg1 + arg2 # total在這里是局部變量.
print "函數(shù)內(nèi)是局部變量 : ", total
return total
#調(diào)用sum函數(shù)sum( 10, 20 )print "函數(shù)外是全局變量 : ", total
以上實(shí)例輸出結(jié)果:
函數(shù)內(nèi)是局部變量 : ?30函數(shù)外是全局變量 : ?0
其中有兩個(gè)非常漂亮的指數(shù)函數(shù)圖就是用python的matplotlib畫(huà)出來(lái)的。這一期,我們將要介紹如何利用python繪制出如下指數(shù)函數(shù)。
圖 1 a1圖 1 a1
我們知道當(dāng)0 ,指數(shù)函數(shù) 是單調(diào)遞減的,當(dāng)a1 時(shí),指數(shù)函數(shù)是單調(diào)遞增的。所以我們首先要定義出指數(shù)函數(shù),將a值做不同初始化
import math
...
def exponential_func(x, a): #定義指數(shù)函數(shù)
y=math.pow(a, x)
return y
然后,利用numpy構(gòu)造出自變量,利用上面定義的指數(shù)函數(shù)來(lái)計(jì)算出因變量
X=np.linspace(-4, 4, 40) #構(gòu)造自變量組
Y=[exponential_func(x) for x in X] #求函數(shù)值
有了自變量和因變量的一些散點(diǎn),那么就可以模擬我們平時(shí)畫(huà)函數(shù)操作——描點(diǎn)繪圖,利用下面代碼就可以實(shí)現(xiàn)
import math
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist #導(dǎo)入坐標(biāo)軸加工模塊
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
fig=plt.figure(figsize=(6,4)) #新建畫(huà)布
ax=axisartist.Subplot(fig,111) #使用axisartist.Subplot方法創(chuàng)建一個(gè)繪圖區(qū)對(duì)象ax
fig.add_axes(ax) #將繪圖區(qū)對(duì)象添加到畫(huà)布中
def exponential_func(x, a=2): #定義指數(shù)函數(shù)
y=math.pow(a, x)
return y
X=np.linspace(-4, 4, 40) #構(gòu)造自變量組
Y=[exponential_func(x) for x in X] #求函數(shù)值
ax.plot(X, Y) #繪制指數(shù)函數(shù)
plt.show()
圖 2 a=2
圖2雖簡(jiǎn)單,但麻雀雖小五臟俱全,指數(shù)函數(shù)該有都有,接下來(lái)是如何讓其看起來(lái)像我們?cè)谧鲌D紙上面畫(huà)的那么美觀,這里重點(diǎn)介紹axisartist 坐標(biāo)軸加工類(lèi),在的時(shí)候我們已經(jīng)用過(guò)了,這里就不再多說(shuō)了。我們只需要在上面代碼后面加上一些代碼來(lái)將坐標(biāo)軸好好打扮一番。
圖 3 a1 完整代碼# -*- coding: utf-8 -*-圖 3 a1 完整代碼# -*- coding: utf-8 -*-"""Created on Sun Feb 16 10:19:23 2020project name:@author: 帥帥de三叔"""import mathimport numpy as npimport matplotlib.pyplot as pltimport mp
在前面已經(jīng)多次提到函數(shù)這個(gè)概念,之所以沒(méi)有解釋什么是函數(shù),是因?yàn)槌绦蛑械暮瘮?shù)和數(shù)學(xué)中的函數(shù)差不多,如input()、range()等都是函數(shù),這些都是Python的標(biāo)準(zhǔn)函數(shù),直接使用就可以了。根據(jù)需要,用戶(hù)也可以自定義函數(shù)。
12.1 函數(shù)
函數(shù)的結(jié)構(gòu):
def 函數(shù)名(參數(shù)):
函數(shù)體
return 返回值
例如:數(shù)學(xué)中的函數(shù)f(x)=2x+5在Python中可以定義如下:
def f(x):
y=2*x+5
return(y)
如果x取值為3,可以使用如下語(yǔ)句調(diào)用函數(shù):
f(3)
下面給出完整的程序代碼:
def f(x):
y=2*x+5
return(y)
res=f(3)
print(res)
運(yùn)行結(jié)果:11
如上例中的x是函數(shù)f(x)的參數(shù),有時(shí)也被稱(chēng)為形式參數(shù)(簡(jiǎn)稱(chēng)形參),在函數(shù)被調(diào)用時(shí),x被具體的值3替換y就是函數(shù)的返回值,這個(gè)值3也被稱(chēng)為實(shí)際參數(shù)(簡(jiǎn)稱(chēng)實(shí)參)。
上例中的y是函數(shù)f(x)的返回值。并不是所有的函數(shù)都有參數(shù)和返回值。如下面的函數(shù):
def func():
print('此為無(wú)參數(shù)傳遞、無(wú)返回值的函數(shù)')
func()
輸出結(jié)果:此為無(wú)參數(shù)傳遞、無(wú)返回值的函數(shù)
可以看出,該函數(shù)func()無(wú)參數(shù),故調(diào)用時(shí)不用賦給參數(shù)值。
函數(shù)也可以有多個(gè)參數(shù),如f(x,y)=x2+y2,可用Python語(yǔ)言定義如下:
def f(x,y):
z=x**2+y**2
return z
print(f(2,3)) #調(diào)用函數(shù)f(x,y)
輸出結(jié)果:13
也可以通過(guò)直接給參數(shù)列表中的參數(shù)賦值的方法,為參數(shù)添加默認(rèn)值,如果用戶(hù)賦予參數(shù)值,則按照用戶(hù)賦值執(zhí)行,否則使用默認(rèn)值。例如:
def f(x,y=3):
z=x**2+y**2
return z
若調(diào)用時(shí)參數(shù)列表為(2,1),即x賦值為2,y賦值為1:
print(f(2,1))
輸出結(jié)果為:5
若調(diào)用時(shí)參數(shù)列表為(2),即x賦值為2,y賦值省缺,則y使用默認(rèn)值:
print(f(2))
輸出結(jié)果為:13
回調(diào)函數(shù),又稱(chēng)函數(shù)回調(diào),是將函數(shù)作為另一函數(shù)的參數(shù)。
例如:
def func(fun,m,n):
fun(m,n)
def f_add(m,n):
print('m+n=',m+n)
def f_mult(m,n):
print('m*n=',m*n)
func(f_add,2,3)
func(f_mult,2,3)
輸出結(jié)果:
m+n= 5
m*n= 6
在f_add(m,n)和f_mult(m,n)被定義前,func(fun,m,n)中的fun(m,n)就已經(jīng)調(diào)用了這兩個(gè)函數(shù),即“先調(diào)用后定義”,這也是回調(diào)函數(shù)的特點(diǎn)。
如果無(wú)法預(yù)知參數(shù)的個(gè)數(shù),可以在參數(shù)前面加上*號(hào),這種參數(shù)實(shí)際上對(duì)應(yīng)元組類(lèi)型。譬如,參會(huì)的人數(shù)事先不能確定,只能根據(jù)與會(huì)人員名單輸入:
def func(*names):
print('今天與會(huì)人員有:')
for name in names:
print(name)
func('張小兵','陳曉梅','李大海','王長(zhǎng)江')
運(yùn)行后,輸出結(jié)果為:
今天與會(huì)人員有:
張小兵
陳曉梅
李大海
王長(zhǎng)江
參數(shù)為字典類(lèi)型,需要在參數(shù)前面加上**號(hào)。
def func(**kwargs):
for i in kwargs:
print(i,kwargs[i])
func(a='a1',b='b1',c='c1')
輸出結(jié)果為:
a a1
b b1
c c1
一個(gè)有趣的實(shí)例:
def func(x,y,z,*args,**kwargs):
print(x,y,z)
print(args)
print(kwargs)
func('a','b','c','Python','is easy',py='python',j='java',ph='php')
輸出結(jié)果:
a b c # 前三個(gè)實(shí)參賦給前三個(gè)形參
('Python', 'is easy') # *args接收元組數(shù)據(jù)
{'py': 'python', 'j': 'java', 'ph': 'php'} # **kwargs接收字典數(shù)據(jù)
12.2 變量的作用域
變量的作用域即變量的有效范圍,可分為全局變量和局部變量。
局部變量
在函數(shù)中定義的變量就是局部變量,局部變量的作用域僅限于函數(shù)內(nèi)部使用。
全局變量
在主程序中定義的變量就是全局變量,但在函數(shù)中用關(guān)鍵字global修飾的變量也可以當(dāng)做全局變量來(lái)使用。
全局變量的作用域是整個(gè)程序,也就是說(shuō),全局變量可以在整個(gè)程序中可以訪(fǎng)問(wèn)。
下面通過(guò)實(shí)例去討論:
程序1:
a=1 # a為全局變量
def a_add():
print('a的初值:',a) # 在函數(shù)中讀取a的值
a_add() # 調(diào)用函數(shù)a_add()
a+=1 # 主程序語(yǔ)句,a增加1
print('a現(xiàn)在的值是:',a) # 主程序語(yǔ)句,讀取a的值
運(yùn)行結(jié)果:
a的初值: 1
a現(xiàn)在的值是: 2
這個(gè)結(jié)果和我們想象的一樣,全局變量a既可以在主程序中讀取,也可以在子程序(函數(shù))中讀取。
程序2:
a=1
def a_add():
a+=1
print('a的初值:',a)
a_add()
print('a現(xiàn)在的值是:',a)
運(yùn)行程序1時(shí)出現(xiàn)如下錯(cuò)誤提示:
UnboundLocalError: local variable 'a' referenced before assignment
意思是:局部變量'a'在賦值之前被引用。
從語(yǔ)法上來(lái)講,該程序沒(méi)有錯(cuò)誤。首先定義了一個(gè)全局變量a并賦值為1,又定義了一個(gè)函數(shù)a_add(),函數(shù)內(nèi)的語(yǔ)句a+=1就是出錯(cuò)的根源,雖然我們的初衷是想讓全局變量a的值增加1,但從錯(cuò)誤提示看,這個(gè)語(yǔ)句中的a并不是全局變量,而是局部變量??磥?lái),在函數(shù)中讀取全局變量的值是沒(méi)有問(wèn)題的(在程序1中已經(jīng)得到了驗(yàn)證),但要在函數(shù)中改變?nèi)肿兞康闹凳遣恍械模ㄔ诔绦?的錯(cuò)誤提示a+=1中的a 是局部變量,而非全局變量)。
怎樣解決這個(gè)問(wèn)題?
程序3:
a=1
def a_add(x):
x+=1
return x
print('a的初值:',a)
a=a_add(a)
print('a現(xiàn)在的值是:',a)
運(yùn)行結(jié)果:
a的初值: 1
a現(xiàn)在的值是: 2
結(jié)果的確是正確的,但在函數(shù)a_add(x)中沒(méi)有調(diào)用變量a(沒(méi)有出現(xiàn)變量a)。
程序4:
a=1
def a_add(a):
a+=1
return a
print('a的初值:',a)
a=a_add(a)
print('a現(xiàn)在的值是:',a)
運(yùn)行結(jié)果:
a的初值: 1
a現(xiàn)在的值是: 2
對(duì)比程序4和程序3不難發(fā)現(xiàn),其實(shí)程序4只是簡(jiǎn)單的把函數(shù)的參數(shù)x變成了a,這個(gè)a的實(shí)質(zhì)和程序3中的x還是一樣的。這進(jìn)一步證實(shí),函數(shù)中的a是局部變量,與主程序的全局變量a有著本質(zhì)的區(qū)別。
程序5:
a=1
def a_add():
global a
a+=1
print('a的初值:',a)
a_add()
print('a現(xiàn)在的值是:',a)
運(yùn)行結(jié)果:
a的初值: 1
a現(xiàn)在的值是: 2
程序5和程序2相比較,僅僅是在函數(shù)中添加了一個(gè)定義“global a”,此時(shí)的局部變量a就可以當(dāng)做全局變量使用,由于它和全局變量a同名,自然也就不用區(qū)分a究竟是全局變量還是局部變量了,在主程序和該函數(shù)內(nèi)都可以訪(fǎng)問(wèn)、修改變量a的值了。
雖然使用global可使變量使用起來(lái)非常方便,但也容易引起混淆,故在使用過(guò)程中還是謹(jǐn)慎為好。
12.3 函數(shù)的遞歸與嵌套
遞歸,就是函數(shù)調(diào)用它自身。遞歸必須設(shè)置停止條件,否則函數(shù)將無(wú)法終止,形成死循環(huán)。
以計(jì)算階乘為例:
def func(n):
if n==1:
return 1
else:
return n*func(n-1) #func( )調(diào)用func( )
print(func(5))
運(yùn)行結(jié)果為:120
嵌套,指在函數(shù)中調(diào)用另外的函數(shù)。這是程序中常見(jiàn)的一種結(jié)構(gòu),在此不再贅述。
匿名函數(shù)
Python中可以在參數(shù)前加上關(guān)鍵字lambda定義一個(gè)匿名函數(shù),這樣的函數(shù)一般都屬于“一次性”的。
例如:
程序1:這是一個(gè)常規(guī)的函數(shù)定義和調(diào)用。
def f_add(x,y):
return x+y
print(f_add(2,3))
輸出結(jié)果:5
程序2:使用lambda定義匿名函數(shù)。
f_add=lambda x,y:x+y
print(f_add(2,3))
輸出結(jié)果:5
從上面的代碼可以看出,使用lambda僅僅減少了一行代碼。f_add=lambda x,y:x+y中的f_add不是變量名,而是函數(shù)名。程序1和程序2的print( )語(yǔ)句中的參數(shù)都是一樣的——調(diào)用函數(shù)f_add( )。所以,匿名函數(shù)并沒(méi)有太多的優(yōu)點(diǎn)。
我覺(jué)得你可以這么理解:
假設(shè)你原本的數(shù)據(jù)是一個(gè)pandas dataframe; 那你第一個(gè)函數(shù)get_fund()相當(dāng)于是適用于dataframe這個(gè)類(lèi)的函數(shù)。這個(gè)函數(shù)用完后,你可以把output當(dāng)做一個(gè)新的input去看,在這個(gè)數(shù)據(jù)結(jié)構(gòu)上又有適用的函數(shù),我們這里用的是filter,以此類(lèi)推。為了減少代碼量,我們可以以你說(shuō)的多個(gè)點(diǎn)的形式寫(xiě)成一行。
希望對(duì)你有幫助。
lst = [] #定義一個(gè)空列表
str = raw_input("請(qǐng)輸入數(shù)值,用空格隔開(kāi):")
lst1 = str.split(" ")#lst1用來(lái)存儲(chǔ)輸入的字符串,用空格分割
i = 0
while i = len(lst1)+1:
lst.a(chǎn)ppend(int(lst1.pop()))#將lst1的數(shù)據(jù)轉(zhuǎn)換為整型并賦值給lst
i += 1
#print(lst)
def sum(list):
"對(duì)列表的數(shù)值求和"
s = 0
for x in list:
s += x
return s
def average(list):
"對(duì)列表數(shù)據(jù)求平均值"
avg = 0
avg = sum(list)/(len(list)*1.0) #調(diào)用sum函數(shù)求和
return avg
print("avg = %f"%average(lst))
擴(kuò)展資料:
for循環(huán)小括號(hào)里第一個(gè)“;”號(hào)前為一個(gè)為不參與循環(huán)的單次表達(dá)式,其可作為某一變量的初始化賦值語(yǔ)句, 用來(lái)給循環(huán)控制變量賦初值; 也可用來(lái)計(jì)算其它與for循環(huán)無(wú)關(guān)但先于循環(huán)部分處理的一個(gè)表達(dá)式。
執(zhí)行的中間循環(huán)體可以為一個(gè)語(yǔ)句,也可以為多個(gè)語(yǔ)句,當(dāng)中間循環(huán)體只有一個(gè)語(yǔ)句時(shí),其大括號(hào){}可以省略,執(zhí)行完中間循環(huán)體后接著執(zhí)行末尾循環(huán)體。
執(zhí)行末尾循環(huán)體后將再次進(jìn)行條件判斷,若條件還成立,則繼續(xù)重復(fù)上述循環(huán),當(dāng)條件不成立時(shí)則跳出當(dāng)下for循環(huán)。
params
就是(5, 5)
(5,) * 2 ,就是2個(gè)5的元組,乘號(hào)可以理解成相加。"*" * 30就是30個(gè)“*"的字符串
*params作為參數(shù),前面的*號(hào)就是把params元組分解成元素的意思,這樣就分開(kāi)成為2個(gè)參數(shù)了。實(shí)際上傳遞給了x,y
于是就執(zhí)行了power(5,5)