python學習筆記(六)——函式

weixin_30924079發表於2020-04-04

                      函式

  有了語句我們可以做很多事,但是如果要編寫大型或更復雜的程式,那麼程式碼的重用性值得我們考慮,因此就有了函式,函式其實可以重複利用的程式碼塊。回憶一下我們N年前用C++痛苦的編寫一個斐波那契數列,現用python是多麼容易的實現:

fibs=[0,1]
num=input('How much numbers do you want:') #注意這裡是input,或者是int(raw_input("")),不然會出錯
for i in range(num-2):
    fibs.append(fibs[-2]+fibs[-1])
print fibs
raw_input('press any key to exit!')

  函式可以呼叫,它執行某種操作並且可能返回值,內建的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'

 

 

 

轉載於:https://www.cnblogs.com/zhoujie/archive/2013/04/09/python6.html

相關文章