1唆貌、Python之什么是函數(shù)
2滑潘、Python之調(diào)用函數(shù)
Python內(nèi)置了很多有用的函數(shù),我們可以直接調(diào)用锨咙。
要調(diào)用一個(gè)函數(shù)语卤,需要知道函數(shù)的名稱和參數(shù),比如求絕對(duì)值的函數(shù) abs酪刀,它接收一個(gè)參數(shù)粹舵。
可以直接從Python的官方網(wǎng)站查看文檔:
http://docs.python.org/2/library/functions.html#abs
也可以在交互式命令行通過?help(abs)查看abs函數(shù)的幫助信息。
調(diào)用abs?函數(shù):
>>> abs(100)
100
>>> abs(-20)
20
>>> abs(12.34)
12.34
調(diào)用函數(shù)的時(shí)候骂倘,如果傳入的參數(shù)數(shù)量不對(duì)眼滤,會(huì)報(bào)TypeError的錯(cuò)誤,并且Python會(huì)明確地告訴你:abs()有且僅有1個(gè)參數(shù)稠茂,但給出了兩個(gè):
>>> abs(1, 2)
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)
如果傳入的參數(shù)數(shù)量是對(duì)的柠偶,但參數(shù)類型不能被函數(shù)所接受,也會(huì)報(bào)TypeError的錯(cuò)誤睬关,并且給出錯(cuò)誤信息:str是錯(cuò)誤的參數(shù)類型:
>>> abs('a')
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'
而比較函數(shù)cmp(x, y)?就需要兩個(gè)參數(shù)诱担,如果?x<y,返回?-1电爹,如果?x==y蔫仙,返回?0,如果?x>y丐箩,返回?1:
>>> cmp(1, 2)
-1
>>> cmp(2, 1)
1
>>> cmp(3, 3)
0
Python內(nèi)置的常用函數(shù)還包括數(shù)據(jù)類型轉(zhuǎn)換函數(shù)摇邦,比如? ?int()函數(shù)可以把其他數(shù)據(jù)類型轉(zhuǎn)換為整數(shù):
>>> int('123')
123
>>> int(12.34)
12
str()函數(shù)把其他類型轉(zhuǎn)換成 str:
>>> str(123)
'123'
>>> str(1.23)
'1.23'
sum()函數(shù)接受一個(gè)list作為參數(shù)恤煞,并返回list所有元素之和。請(qǐng)計(jì)算 1*1 + 2*2 + 3*3 + ... + 100*100施籍。
L = []
x = 1
while x<=100:
? ? L.append(x * x)
? ? x = x+1
print sum(L)
3居扒、Python之編寫函數(shù)
在Python中,定義一個(gè)函數(shù)要使用?def?語句丑慎,依次寫出函數(shù)名喜喂、括號(hào)、括號(hào)中的參數(shù)和冒號(hào):竿裂,然后玉吁,在縮進(jìn)塊中編寫函數(shù)體,函數(shù)的返回值用return?語句返回腻异。
我們以自定義一個(gè)求絕對(duì)值的 my_abs 函數(shù)為例:
defmy_abs(x):ifx >= 0:return x else:return -x
請(qǐng)注意进副,函數(shù)體內(nèi)部的語句在執(zhí)行時(shí),一旦執(zhí)行到return時(shí)悔常,函數(shù)就執(zhí)行完畢影斑,并將結(jié)果返回。因此这嚣,函數(shù)內(nèi)部通過條件判斷和循環(huán)可以實(shí)現(xiàn)非常復(fù)雜的邏輯鸥昏。
如果沒有return語句,函數(shù)執(zhí)行完畢后也會(huì)返回結(jié)果姐帚,只是結(jié)果為 None。
return None可以簡(jiǎn)寫為return障涯。
任務(wù)
請(qǐng)定義一個(gè) square_of_sum 函數(shù)罐旗,它接受一個(gè)list,返回list中每個(gè)元素平方的和唯蝶。
def square_of_sum(L):
? ? sum = 0
? ? for x in L:
? ? ? ? sum = sum + x * x
? ? return sum
print square_of_sum([1, 2, 3, 4, 5])
print square_of_sum([-5, 0, 5, 15, 25])
4九秀、Python函數(shù)之返回多值
比如在游戲中經(jīng)常需要從一個(gè)點(diǎn)移動(dòng)到另一個(gè)點(diǎn),給出坐標(biāo)粘我、位移和角度鼓蜒,就可以計(jì)算出新的坐標(biāo):
# math包提供了sin()和cos()函數(shù),我們先用import引用它:
import math
def move(x, y, step, angle):
? ? nx = x + step * math.cos(angle)
? ? ny = y - step * math.sin(angle)
? ? return nx, ny
這樣我們就可以同時(shí)獲得返回值:
>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print x, y
151.961524227 70.0
但其實(shí)這只是一種假象征字,Python函數(shù)返回的仍然是單一值:
>>> r = move(100, 100, 60, math.pi / 6)
>>> print r
(151.96152422706632, 70.0)
用print打印返回結(jié)果都弹,原來返回值是一個(gè)tuple!
但是匙姜,在語法上畅厢,返回一個(gè)tuple可以省略括號(hào),而多個(gè)變量可以同時(shí)接收一個(gè)tuple氮昧,按位置賦給對(duì)應(yīng)的值框杜,所以浦楣,Python的函數(shù)返回多值其實(shí)就是返回一個(gè)tuple,但寫起來更方便咪辱。
任務(wù)
一元二次方程的定義是:ax2 + bx + c = 0
請(qǐng)編寫一個(gè)函數(shù)振劳,返回一元二次方程的兩個(gè)解。
注意:Python的math包提供了sqrt()函數(shù)用于計(jì)算平方根油狂。
import math
def quadratic_equation(a, b, c):
? ? dt = b*b - 4*a*c
? ? if dt < 0:
? ? ? ? return
? ? elif dt == 0:
? ? ? ? return -b/(2*a)
? ? else:
? ? ? ? x1 = (-b+math.sqrt(dt))/(2*a)
? ? ? ? x2 = (-b-math.sqrt(dt))/(2*a)
? ? ? ? return x1, x2
print quadratic_equation(2, 3, 0)
print quadratic_equation(1, -6, 5)
5历恐、Python之遞歸函數(shù)
在函數(shù)內(nèi)部,可以調(diào)用其他函數(shù)选调。如果一個(gè)函數(shù)在內(nèi)部調(diào)用自身本身夹供,這個(gè)函數(shù)就是遞歸函數(shù)。
舉個(gè)例子仁堪,我們來計(jì)算階乘?n! = 1 * 2 * 3 * ... * n哮洽,用函數(shù)fact(n)表示,可以看出:
fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n
所以弦聂,fact(n)可以表示為?n * fact(n-1)鸟辅,只有n=1時(shí)需要特殊處理。
于是莺葫,fact(n)用遞歸的方式寫出來就是:
def fact(n):
? ? if n==1:
? ? ? ? return 1
? ? return n * fact(n - 1)
上面就是一個(gè)遞歸函數(shù)匪凉。可以試試:
6捺檬、Python之定義默認(rèn)參數(shù)
定義函數(shù)的時(shí)候再层,還可以有默認(rèn)參數(shù)。
例如Python自帶的?int()?函數(shù),其實(shí)就有兩個(gè)參數(shù),我們既可以傳一個(gè)參數(shù)故慈,又可以傳兩個(gè)參數(shù):
>>> int('123')
123
>>> int('123', 8)
83
int()函數(shù)的第二個(gè)參數(shù)是轉(zhuǎn)換進(jìn)制,如果不傳蛋济,默認(rèn)是十進(jìn)制 (base=10),如果傳了炮叶,就用傳入的參數(shù)碗旅。
可見,函數(shù)的默認(rèn)參數(shù)的作用是簡(jiǎn)化調(diào)用镜悉,你只需要把必須的參數(shù)傳進(jìn)去祟辟。但是在需要的時(shí)候,又可以傳入額外的參數(shù)來覆蓋默認(rèn)參數(shù)值积瞒。
我們來定義一個(gè)計(jì)算 x 的N次方的函數(shù):
def power(x, n):
? ? s = 1
? ? while n > 0:
? ? ? ? n = n - 1
? ? ? ? s = s * x
? ? return s
假設(shè)計(jì)算平方的次數(shù)最多川尖,我們就可以把 n 的默認(rèn)值設(shè)定為 2:
def power(x, n=2):
? ? s = 1
? ? while n > 0:
? ? ? ? n = n - 1
? ? ? ? s = s * x
? ? return s
這樣一來,計(jì)算平方就不需要傳入兩個(gè)參數(shù)了:
>>> power(5)
25
由于函數(shù)的參數(shù)按從左到右的順序匹配,所以默認(rèn)參數(shù)只能定義在必需參數(shù)的后面:
# OK:
????def ?fn1(a, b=1, c=2):? ??
????????pass
# Error:
????def fn2(a=1, b):? ??
? ? ? ? pass
7叮喳、Python之定義可變參數(shù)
如果想讓一個(gè)函數(shù)能接受任意個(gè)參數(shù)被芳,我們就可以定義一個(gè)可變參數(shù):
deffn(*args):print args
可變參數(shù)的名字前面有個(gè)*?號(hào),我們可以傳入0個(gè)馍悟、1個(gè)或多個(gè)參數(shù)給可變參數(shù):
>>> fn()
()
>>> fn('a')
('a',)
>>> fn('a', 'b')
('a', 'b')
>>> fn('a', 'b', 'c')
('a', 'b', 'c')
可變參數(shù)也不是很神秘畔濒,Python解釋器會(huì)把傳入的一組參數(shù)組裝成一個(gè)tuple傳遞給可變參數(shù),因此锣咒,在函數(shù)內(nèi)部侵状,直接把變量?args?看成一個(gè)tuple?就好了。
定義可變參數(shù)的目的也是為了簡(jiǎn)化調(diào)用毅整。假設(shè)我們要計(jì)算任意個(gè)數(shù)的平均值趣兄,就可以定義一個(gè)可變參數(shù):
def average(*args):
? ? sum = 0.0
? ? if len(args) == 0:
? ? ? ? return sum
? ? for x in args:
? ? ? ? sum = sum +x
? ? return sum / len(args)
這樣,在調(diào)用的時(shí)候悼嫉,可以這樣寫:
>>> average()
0
>>> average(1, 2)
1.5
>>> average(1, 2, 2, 3, 4)
2.4