Python|函數功能簡單介紹

LaverneMati 8年前發布 | 7K 次閱讀 Python Python開發

大家好,我是廈門大學經濟學院16級新生。作為一個python新手,今天為大家介紹一下Python中函數功能的簡單應用。(考試周表示鴨梨山大)

本教程適用于Python 2.7,部分語法與Python 3.x有區別。

看懂本教程你需要了解:

  • Python的數據類型
  • Python的條件判斷和循環
  • Python中的list,tuple的簡單使用

函數是對程序邏輯進行結構化或過程化的一種編程方法。能將整塊代碼巧妙地隔離成易于管理的小塊,這樣在以后的python程序編寫中十分重要,可以使你的程序更加簡潔,有邏輯,可讀性強。

本文章的內容有:

  1. 函數的調用
  2. 定義函數
  3. 函數的參數
  4. 幾種高階函數的使用

一.函數的調用

Python內置了很多有用的函數,我們可以直接調用。要調用一個函數,需要知道函數的名稱和參數,比如求絕對值的函數abs,只有一個參數。

也可以在交互式環境中用help()查看關于調用函數的相關信息

>>> abs(100)
100
>>> help(abs)
Help on built-in function abs in module __builtin__:

abs(...)
    abs(number) -> number

    Return the absolute value of the argument.

Python中已經有很多非常實用的函數,如果應用的好,可以大大提高效率。

二.定義函數

那么現在一定有小伙伴要問,我們能不能定義自己想要的函數?當然可以。

在Python中,定義一個函數要使用def語句,依次寫出函數名、括號、括號中的參數和冒號:,然后,在縮進塊中編寫函數體,函數的返回值用return語句返回。

我們以自定義一個求絕對值的myabs函數為例:

def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

大家可以自己試驗一下代碼。請注意:

1.Python的縮進規則。

2.函數體內部的語句在執行時,一旦執行到return時,函數就執行完畢,并將結果返回。因此,函數內部通過條件判斷和循環可以實現非常復雜的邏輯。如果沒有return語句,函數執行完畢后也會返回結果,只是結果為None。

Python函數返回值 有兩種形式: 1 返回一個值。 2 返回多個值。

現看看 返回一個值 的:

>>>def firstvalue(a,b):
    c = a + b
    return c
>>> print firstvalue(1,2)
3

再看看 返回多個值 的:

>>>def secondvalue(a,b):
    c = a + b
    return (a,b,c)
>>> x,y,z = secondvalue(1,2)
>>> print 'x=',x,'y=',y,'z=',z
x= 1 y= 2 z= 3

三.函數的參數

Python的函數定義非常簡單,但靈活度卻非常大。除了正常定義的必選參數外,還可以使用默認參數、可變參數和關鍵字參數,使得函數定義出來的接口,不但能處理復雜的參數,還可以簡化調用者的代碼。

默認參數

我們來舉一個例子。比如現在我們想要計算x的立方。接著上一節的內容,我們使用多參數函數:

>>>def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s
>>> power(5, 2)
25
>>> power(5, 3)
125

這個函數可以計算任意數的n次方。但是請讀者試一試輸入power(5)你會發現報錯,這是因為你只輸入了一個參數。

但是如果我們經常使用的只是計算x的立方,為了簡化輸入,我們可以這樣:

>>>def power(x, n=3):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

這樣,當我們調用power(5)時,相當于調用power(5, 2):

從上面的例子可以看出,默認參數可以簡化函數的調用。設置默認參數時,有幾點要注意:

一 是必選參數在前,默認參數在后,否則Python的解釋器會報錯(思考一下為什么默認參數不能放在必選參數前面);

是如何設置默認參數。當函數有多個參數時,把變化大的參數放前面,變化小的參數放后面。變化小的參數就可以作為默認參數。

>>> def func(a,b=7,c=10):
...     print a,b,c
...
>>> func(2)
2 7 10
>>> func(2,b=5)
2 5 10
>>> func(2,c=6)
2 7 6

其中默認參數有一些坑,提示:(默認參數一定要用不可變對象,如果是可變對象,運行會有邏輯錯誤!比如不能把默認參數定義為可變的list)雖然有辦法解決但還是盡量避免。

可變參數

在Python函數中,還可以定義可變參數。顧名思義,可變參數就是傳入的參數個數是可變的,可以是1個、2個到任意個,還可以是0個。

比如我們計算a平方 + b平方 + c平方 + ……。

def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

這是想要計算需要把numbers定義成一個list或tuple,才能使用for in循環把list中的數字調用出來用于計算。

>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84

為了簡化這一步,我們使用可變參數。定義可變參數和定義list或tuple參數相比,僅僅在參數前面加了一個*號。在函數內部,參數numbers接收到的是一個tuple,因此,函數代碼完全不變。但是,調用該函數時,可以傳入任意個參數,包括0個參數:

def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

這是只需要輸入calc(1,2,3)即可。

如果已經有一個list或者tuple,要調用一個可變參數怎么辦?可以這樣做:

>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2])
14

這種寫法當然是可行的,問題是太繁瑣,所以Python允許你在list或tuple前面加一個*號,把list或tuple的元素變成可變參數傳進去:

>>> nums = [1, 2, 3]
>>> calc(*nums)
14

這種寫法相當有用,而且很常見。可見*可以把元素變為可變參數從而可以更靈活的使用。

還有其他的參數如 關鍵字參數 ,和有這幾種參數一起使用而得到的 組合參數 。這些就不詳細介紹了。(感覺沒咋用啊)

比如我們給個組合參數的例子,我們使用默認參數和可變參數:

def func(a, b, c=0, *args):
    print 'a =', a, 'b =', b, 'c =', c, 'args =', args
>>> func(1, 2)
a = 1 b = 2 c = 0 args = ()
>>> func(1, 2, c=3)
a = 1 b = 2 c = 3 args = ()
>>> func(1,2,3,'a','b')
a = 1 b = 2 c = 3 args = ('a', 'b')

四.幾種高階函數的使用

這一部分可能內容比較復雜,所以我們重點講解幾個用以處理list的高階函數,來體會Python中函數的意義。Python是一門非常強大的語言,其中有很多功能就7體現在對函數的抽象應用之中。其中變量可以指向函數,函數的參數能接收變量,比如:

>>> def f(x):
     return x+1

>>> a=f
>>> a(2)
3

那么一個函數就可以接收另一個函數作為參數,這種函數就稱之為高階函數。

一個最簡單的高階函數:

def add(x, y, f):
    return f(x) + f(y)

>>> add(-2,-9,abs)
    #令a=-2,b=-9,f=abs 
11

現在我們可以看出Python中函數是十分抽象的。接下來介紹幾種常用的高階函數。

map

map()函數接收兩個參數,一個是函數,一個是序列,map將傳入的函數依次作用到序列的每個元素,并把結果作為新的list返回。所以map是處理序列的有力工具之一。

來個例子:

>>> def add(x):
...     return x+100
... 
>>> a = [11,22,33]
>>> map(add,a)
[111, 122, 133]

即實現了讓一個list中所有元素都加上100的操作,同理可以定義別的函數或者使用Python的自帶函數導入map中,完成對list中元素的處理。例如:

>>> map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])
['1', '2', '3', '4', '5', '6', '7', '8', '9']

reduce

map是將函數應用于list中的每個元素,從而得到一個新的list,而reduce則是將list中的元素利用函數累計運算類似于復合函數。

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

我們來舉一個例子,比如我們自己定義一個求和函數。

>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1,2,3])
6

通過使用reduce我們可以使單個函數的功能大大加強。

比如一個二進制轉十進制轉換器(順便復習一下):

a=[]
def f(x):
    for i in x:
        a.append(int(i))   #上面的程序把數字字符串轉化為整數的list
    def g(x,y):            #在這個地方我們可以再定義一個函數
        return x*2+y       
    return reduce(g,a)       
>>> f('536')
32

(自己編的程序比較簡陋。。)大家可以看到reduce的應用。并發現Python函數定義的靈活性。

filter

Python內建的filter()函數用于過濾序列。

和map()類似,filter()也接收一個函數和一個序列。和map()不同的時,filter()把傳入的函數依次作用于每個元素,然后根據返回值是True還是False決定保留還是丟棄該元素。

例如,在一個list中,刪掉偶數,只保留奇數,可以這么寫:

def is_odd(n):
    return n % 2 == 1

filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
# 結果: [1, 5, 9, 15]

思考題:請嘗試用filter()刪除1~100的素數。(以后會有更好的方法)

sorted

排序原理:

排序也是在程序中經常用到的算法。排序的核心是比較兩個元素的大小。如果是數字,我們可以直接比較,但如果是字符串或者兩個dict呢?直接比較數學上的大小是沒有意義的,因此,比較的過程必須通過函數抽象出來。通常規定,對于兩個元素x和y,如果認為x < y,則返回-1,如果認為x == y,則返回0,如果認為x > y,則返回1,這樣,排序算法就不用關心具體的比較過程,而是根據比較結果直接排序。

>>> sorted([36, 5, 12, 9, 21])
[5, 9, 12, 21, 36]

同樣的sorted()也是一個高階函數。我們可以通過上述排序原理利用自己定義的函數來對一個序列進行排序。比如倒序:

def daoxu(x, y):
    if x > y:
        return -1
    if x < y:
        return 1
    return 0

我們利用這個函數相當于改變了排序的規則(負負得正啊,是不是)

傳入自定義的比較函數daoxu,就可以實現倒序排序:

>>> sorted([36, 5, 12, 9, 21], daoxu)
[36, 21, 12, 9, 5]

默認情況下,對字符串排序,是按照ASCII的大小比較的,由于'Z' < 'a',結果,大寫字母Z會排在小寫字母a的前面。現在,我們提出排序應該忽略大小寫,按照字母序排序。要實現這個算法,不必對現有代碼大加改動,只要我們能定義出忽略大小寫的比較算法就可以:

這是我們的想法就是定義一個函數先把一個list中的字符串全變成小寫,然后再比較順序,這樣就可以忽略大小寫的影響了。

def ignore(s1, s2):
    u1 = s1.upper()
    u2 = s2.upper()
    if u1 < u2:
        return -1
    if u1 > u2:
        return 1
    return 0

現在把這個函數扔到sorted()中來實現我們想要的排序

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], ignore)
['about', 'bob', 'Credit', 'Zoo']

好了以上我們就介紹了四種高階函數。從上述例子可以看出,高階函數的抽象能力是非常強大的,而且,核心代碼可以保持得非常簡潔。

小結:

這篇文章講述的主要是對list進行處理的函數。函數的應用需要經常的練習,并在練習中發現問題,(比如縮進,return的位置都會影響最終結果),有時更需要扎實的數學功底比如上文中素數的提取方法(更好的算法更高效)。

 

 

來自:https://zhuanlan.zhihu.com/p/23339106

 

 本文由用戶 LaverneMati 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!