函數
有了語句我們可以做很多事,但是如果要編寫大型或更復雜的程序,那麼代碼的重用性值得我們考慮,因此就有了函數,函數其實可以重複利用的代碼塊。回憶一下我們N年前用C++痛苦的編寫一個斐波那契數列,現用python是多麼容易的實現:
|
函數可以調用,它執行某種操作並且可能返回值,內建的callable函數(python3中無此函數)可以判斷函數是否可以調用:
>>> import math >>> x=1 >>> y=math.sqrt >>> callable(x) False >>> callable(y) True
創建函數——用def關鍵字來定義
>>> def fibs(num): #創建函數 result=[0,1] for i in range(num-2): result.append(result[-2]+result[-1]) return result >>> fibs(10) #調用函數 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] >>> fibs(15) #調用函數 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
記錄函數
要想給函數寫文檔讓函數容易理解的話,除了寫註釋外還可以寫文檔字符串,它作爲函數的一部分進行存儲,並且可以調用查看:
>>> def square(x): 'caculate the square of the number x.' #插入文檔字符串 return x*x >>> square.func_doc #訪問文檔字符串 'caculate the square of the number x.' (__doc是函數屬性,輸入square.,然後按tab鍵,能看到所有的函數屬性)
函數參數
函數的定義和調用都比較簡單,但是函數的用法是體現在它的參數上的,這個比較複雜。
(1)、普通形參
>>> def printMax(a, b): if a > b: print a, 'is maximum' else: print b, 'is maximum' >>> printMax (5,3) 5 is maximum
(2)、默認參數值
>>> def say(message, times = 2): print message * times >>> say('hello') hellohello >>> say(4) 8
(3)、關鍵參數
>>> def func(a, b=5, c=10): print 'a is', a, 'and b is', b, 'and c is', c >>> func(4) a is 4 and b is 5 and c is 10
(4)、可變長度參數
1)、*非關鍵字可變長參數(元組)
>>> def tupleVarArgs(arg1, arg2 = "defaultB", *theRest): print 'arg 1:', arg1 print 'arg 2:', arg2 for eachXtrArg in theRest: print 'another arg:', eachXtrArg >>> tupleVarArgs('abc') arg 1: abc arg 2: defaultB >>> tupleVarArgs(45,67.8) arg 1: 45 arg 2: 67.8 >>> tupleVarArgs('abc',123,'xyz',456.7) arg 1: abc arg 2: 123 another arg: xyz another arg: 456.7
2)、**關鍵字變量參數(字典)
>>> def dictVarArgs(arg1, arg2 = "defaultB", **theRest):
print 'arg 1:', arg1
print 'arg 2:', arg2
for eachXtrArg in theRest.keys():
print 'Xtra arg %s: %s' %(eachXtrArg, str(theRest[eachXtrArg]))
>>> dictVarArgs(1220, 740.0, c = 'gmail')
arg 1: 1220
arg 2: 740.0
Xtra arg c: gmail
>>> dictVarArgs(arg2 = 'tales', c = 123, d = 'zoo', arg1 = 'my')
arg 1: my
arg 2: tales
Xtra arg c: 123
Xtra arg d: zoo
>>> dictVarArgs('one', d = 10, e = 'zoo', girls = ('Jenny', 'Penny'))
arg 1: one
arg 2: defaultB
Xtra arg girls: ('Jenny', 'Penny')
Xtra arg e: zoo
Xtra arg d: 10
3)、組合使用
>>> def newfoo(arg1, arg2, *t, **d):
print 'arg1 is :', arg1
print 'arg2 is :', arg2
for eacht in t:
print 'add non-keyword:', eacht
for eachd in d.keys():
print "add keyword '%s': %s" %(eachd, d[eachd])
>>>newfoo(10, 20, 30, 40, foo = 50, bar = 60)
arg1 is : 10
arg2 is : 20
add non-keyword: 30
add non-keyword: 40
add keyword 'foo': 50
add keyword 'bar': 60
>>> newfoo(2,4,*(6,8),**{'jzhou':22,'James':45})
arg1 is : 2
arg2 is : 4
add non-keyword: 6
add non-keyword: 8
add keyword 'jzhou': 22
add keyword 'James': 45
>>> atuple=(7,8,9)
>>> adict={'jzhou':22}
>>> newfoo(1,2,3,x=4,y=5,z=6,*atuple ,**adict)
arg1 is : 1
arg2 is : 2
add non-keyword: 3
add non-keyword: 7
add non-keyword: 8
add non-keyword: 9
add keyword 'y': 5
add keyword 'jzhou': 22
add keyword 'z': 6
add keyword 'x': 4
變量
(1)、變量作用域
python能夠改變變量作用域的代碼段是def、class、lamda
>>> def scopetest():
localvar=6;
print(localvar)
>>> scopetest()
6
>>> scopetest(localvar) #在函數外不能訪問lcoalvar
Traceback (most recent call last):
File "<pyshell#74>", line 1, in <module>
scopetest(localvar)
NameError: name 'localvar' is not defined
if/elif/else、try/except/finally、for/while 並不能涉及變量作用域的更改,也就是說他們的代碼塊中的變量,在外部也是可以訪問的
>>> if True:
a=3
print a
else: print 'not equals 3'
3
>>> a #外部也可以訪問
3
(2)、局部變量和全局變量
#局部變量 >>> def func(x): print 'x is', x x = 2 print 'Changed local x to', x >>> x=50 >>> func(x) x is 50 Changed local x to 2 >>> x 50 #全局變量 >>> def func(): global x #定義全局變量x print 'x is', x x = 2 print 'Changed local x to', x >>> x=50 >>> func() x is 50 Changed local x to 2 >>> x 2
lambda匿名函數
使用方法:lambda [arg1[,arg2,arg3,...,argn]] : expression
>>> Factorial = lambda x: x > 1 and x * Factorial(x - 1) or 1 # x>1時求x的階乘,其它返回1 >>> print Factorial(6) # 6! 720 >>> max = lambda a, b: (a > b) and a or b # a>b時返回a,否則返回b >>> print max(2,4) 4 >>> x,y=11,12 >>> print (lambda:x+y)() #使用默認的x,y 23 >>> print (lambda x:x+y)(x) #傳的參數是x,y使用默認的12 23 >>> print (lambda x:x+y)(y) #傳的參數是y,則y替換x 24
Generator生成器
可以保存狀態的函數,用yield指令(不是return)返回一個值,並保存當前整個函數執行狀態,等待下一次調用,如此循環往復,直至函數末尾,發生StopIteration異常。generator利用next()來獲取下一個返回值。
>>> def gen(n): for i in xrange(n): yield i >>> g=gen(5) >>> g.next() 0 >>> g.next() 1 >>> for x in g: print x 2 3 4 >>> print g.next() Traceback (most recent call last): File "<pyshell#128>", line 1, in <module> print g.next() StopIteration #迭代已停止
Iterations迭代器
iter and next函數
>>> L=[1,2,3] >>> I=iter(L) >>> print I.next() 1 >>> print I.next() 2 >>> print I.next() 3 >>> print I.next() Traceback (most recent call last): File "<pyshell#134>", line 1, in <module> print I.next() StopIteration #迭代停止 >>> for x in I: print (x) #已經迭代完了 >>> Y=iter(L) >>> while True: try: X=next(Y) except StopIteration: break print X**2 1 4 9 >>> R=range(3) # R=[0,1,2] 列表 >>> I1,I2=iter(R),iter(R) >>> print next(I1),next(I1),next(I2) 0 1 0
內建函數
(1)、enumerate函數 ——獲得數組,或列表的索引及值
>>> string = 'hello' >>> print list(enumerate(string)) [(0, 'h'), (1, 'e'), (2, 'l'), (3, 'l'), (4, 'o')] >>> for index,value in enumerate(string): print index, value 0 h 1 e 2 l 3 l 4 o
(2)、filter函數
filter(bool_func,seq):此函數的功能相當於過濾器。調用一個布爾函數bool_func來迭代遍歷每個seq中的元素;返回一個使bool_seq返回值爲true的元素的序列。
>>> def f(x):
return x % 2 != 0 and x % 3 != 0
>>> print filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]
(3)、map函數
map(func,seq1[,seq2...]):將函數func作用於給定序列的每個元素,並用一個列表來提供返回值;如果func爲None,func表現爲身份函數,返回一個含有每個序列中元素集合的n個元組的列表。
>>> def cube(x):
return x*x*x
>>> print map(cube,range(1,5))
[1, 8, 27, 64]
>>> print filter (cube,range(1,5))
[1, 2, 3, 4]
>>> print map(lambda x:x*2,[1,2,3,4,[5,6,7]])
[2, 4, 6, 8, [5, 6, 7, 5, 6, 7]]
None參數:
>>> map(None,'abc','xyz123')
[('a', 'x'), ('b', 'y'), ('c', 'z'), (None, '1'), (None, '2'), (None, '3')]
(4)、reduce函數
reduce(func,seq[,init]):func 爲二元函數,將func作用於seq序列的元素,每次攜帶一對(先前的結果以及下一個序列的元素),連續的將現有的結果和下一個值作用在獲得的隨後的結果上,最後減少我們的序列爲一個單一的返回值:如果初始值init給定,第一個比較會是init和第一個序列元素而不是序列的頭兩個元素。
>>> print reduce((lambda x, y: x + y), [1, 2, 3, 4])
10
>>> print reduce((lambda x, y: x * y), [1, 2, 3, 4])
24
(5)、zip函數
zip允許用戶使用for循環訪問平行的多個序列,zip將一個或多個序列作爲參數,然後返回一系列的與序列中項平行的元組。
>>> x, y = [1, 2, 3], [4, 5, 6]
>>> print zip(x, y)
[(1, 4), (2, 5), (3, 6)]
>>> print list(zip(x, y))
[(1, 4), (2, 5), (3, 6)]
>>> print dict(zip(x, y))
{1: 4, 2: 5, 3: 6}
>>> print tuple(zip(x, y))
((1, 4), (2, 5), (3, 6))
>>> T1, T2, T3 = (1,2,3), (4,5,6), (7,8,9)
>>> print list(zip(T1, T2, T3))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> print tuple(zip(T1, T2, T3))
((1, 4, 7), (2, 5, 8), (3, 6, 9))
(6)、type函數——得到對象的類型
>>> type(12)
<type 'int'>
>>> type('hello')
<type 'str'>
>>> type(type(42))
<type 'type'>
>>> type([].append)
<type 'builtin_function_or_method'>
(7)、cmp函數——比較兩個對象是否相等
>>> cmp(1,2)
-1
>>> cmp(3,3)
0
>>> cmp(0xFF,255)
0
(8)、類型轉換
#類型轉換
>>> float(4)
4.0
>>> complex (2.4,8) #轉換爲複數
(2.4+8j)
>>> coerce(1j,123) #複數表示
(1j, (123+0j))
#ASCII轉換
>>> ord('s')
115
>>> chr(115)
's'
#進制轉換
>>> hex(255) #16進制
'0xff'
>>> oct(255) #8進制
'0377'