Python基礎之(七)函數

函數

創建函數

在Python中,規定了一種定義函數的格式,下面的舉例就是一個函數,以這個函數爲例來講明定義函數的格式和調用函數的方法。python

def add_function(a, b): #冒號必須
   c = a + b  #縮進必須
   return c

if __name__ == "__main__":
   result = add_function(2, 3)
   print result               #python3: print(result)

定義函數的格式爲:android

def 函數名(參數1,參數2,...,參數n):

   函數體(語句塊)

幾點說明:git

  • 函數名的命名規則要符合Python中的命名要求。通常用小寫字母和單下劃線、數字等組合,有人習慣用aaBb的樣式,但我不推薦github

  • def是定義函數的關鍵詞,這個簡寫來自英文單詞defineapp

  • 函數名後面是圓括號,括號裏面,能夠有參數列表,也能夠沒有參數函數

  • 千萬不要忘記了括號後面的冒號this

  • 函數體(語句塊),相對於def縮進,按照python習慣,縮進四個空格google

函數命名

Python對命名的通常要求:code

  • 文件名:全小寫,可以使用下劃線orm

  • 函數名:小寫,能夠用下劃線風格單詞以增長可讀性。如:myfunction,my_example_function。注意:混合大小寫僅被容許用於這種風格已經佔據優點的時候,以便保持向後兼容。有的人,喜歡用這樣的命名風格:myFunction,除了第一個單詞首字母外,後面的單詞首字母大寫。這也是能夠的,由於在某些語言中就習慣如此。但我不提倡,這是我很是鮮明的觀點。

  • 函數的參數:命名方式同變量(本質上就是變量)。若是一個參數名稱和Python保留的關鍵字衝突,一般使用一個後綴下劃線會好於使用縮寫或奇怪的拼寫。

  • 變量:變量名所有小寫,由下劃線鏈接各個單詞。如color = WHITE,this_is_a_variable = 1。

調用函數

定義函數

>>> def add(x,y):       #爲了可以更明瞭顯示參數賦值特色,重寫此函數
...     print "x=",x         #分別打印參數賦值結果
...     print "y=",y
...     return x+y
...

普通調用

>>> add(10, 3)           #x=10,y=3
x= 10
y= 3
13

還能夠直接把賦值語句寫到裏面,就明確了參數和對象的關係。固然,這時候順序就不重要了

>>> add(x=10, y=3)       
x= 10
y= 3
13

>>> add(y=10, x=3)
x= 3
y= 10
13

多態調用

>>> def times(x, y=2):       #y的默認值爲2
    ...     print "x=",x                 #Python 3: print("x={}".format(x)),如下相似,從略。
    ...     print "y=",y
    ...     return x*y
    ... 
    >>> times(3)                #x=3,y=2
    x= 3
    y= 2
    6

    >>> times(x=3)              #同上
    x= 3
    y= 2
    6
    
>>> times(3, 4)              #x=3,y=4,y的值再也不是2
x= 3
y= 4
12

>>> times("qiwsir")         #再次體現了多態特色
x= qiwsir
y= 2
'qiwsirqiwsir'

注意事項

下面的若干條,是常見編寫代碼的注意事項:

  1. 別忘了冒號。必定要記住複合語句首行末尾輸入「:」(if,while,for等的第一行)

  2. 從第一行開始。要肯定頂層(無嵌套)程序代碼從第一行開始。

  3. 空白行在交互模式提示符下很重要。模塊文件中符合語句內的空白行常被忽視。可是,當你在交互模式提示符下輸入代碼時,空白行則是會結束語句。

  4. 縮進要一致。避免在塊縮進中混合製表符和空格。

  5. 使用簡潔的for循環,而不是while or range.相比,for循環更易寫,運行起來也更快

  6. 要注意賦值語句中的可變對象。

  7. 不要期待在原處修改的函數會返回結果,好比list.append(),這在可修改的對象中特別注意

  8. 調用函數是,函數名後面必定要跟隨着括號,有時候括號裏面就是空空的,有時候裏面放參數。

  9. 不要在導入和重載中使用擴展名或路徑。

返回值

所謂返回值,就是函數向調用函數的地方返回的數據。

編寫一個斐波那契數列函數:

#!/usr/bin/env python
# coding=utf-8

def fibs(n):
   result = [0,1]
   for i in range(n-2):
       result.append(result[-2] + result[-1])
   return result

if __name__ == "__main__":
   lst = fibs(10)
   print lst

返回多個值元組

>>> def my_fun():
    ...     return 1, 2, 3
    ... 
    >>> a = my_fun()
    >>> a
    (1, 2, 3)

對這個函數,咱們還能夠用這樣的方式來接收函數的返回值。

>>> x, y, z = my_fun()
    >>> x
    1
    >>> y
    2
    >>> z
    3

函數文檔

#!/usr/bin/env python
# coding=utf-8

def fibs(n):
   """
   This is a Fibonacci sequence. #函數文檔
   """
   result = [0,1]
   for i in range(n-2):
       result.append(result[-2] + result[-1])
   return result

if __name__ == "__main__":
   lst = fibs(10)
   print lst
>>> def my_fun():
    ...     """
    ...     This is my function.
    ...     """
    ...     print "I am a craft."
    ... 
    >>> my_fun.__doc__  #調用打印函數文檔
    '\n    This is my function.\n    '

參數收集

函數參數的個數也有不肯定的時候,怎麼解決這個問題呢?Python用這樣的方式解決參數個數的不肯定性。

元組形式

def func(x, *arg): 
    print x         #Python 3請自動修改成print()的格式,下同,從略。
    result = x
    print arg       #輸出經過*arg方式獲得的值
    for i in arg:
        result +=i
    return result

print func(1, 2, 3, 4, 5, 6, 7, 8, 9)    #賦給函數的參數個數不只僅是2個

字典形式

>>> def foo(**kargs):
    ...     print kargs        #Python 3:  print(kargs)
    ...
    >>> foo(a=1,b=2,c=3)    #注意觀察此次賦值的方式和打印的結果
    {'a': 1, 'c': 3, 'b': 2}

一種優雅的方式

>>> def add(x, y):
...     return x + y
... 
>>> add(2, 3)
5

>>> bars = (2, 3)
>>> add(*bars)
5
    
>>> bars = (2, 3, 4) #元組中元素的個數,要跟函數所要求的變量個數一致,否則以下報錯
>>> add(*bars)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (3 given)

綜合

def foo(p1, p2, p3, ...)

>>> def foo(p1, p2, p3):
...     print "p1==>",p1        #Python 3用戶修改成print()格式,下同
...     print "p2==>",p2
...     print "p3==>",p3
... 
>>> foo("python", 1, ["qiwsir","github","io"])   
p1==> python
p2==> 1
p3==> ['qiwsir', 'github', 'io']

def foo(p1=value1, p2=value2, ...)

>>> foo(p3=3, p1=10, p2=222)
    p1==> 10
    p2==> 222
    p3==> 3

>>> def foo(p1, p2=22, p3=33):    #設置了兩個參數p2, p3的默認值
...     print "p1==>",p1
...     print "p2==>",p2
...     print "p3==>",p3
... 
>>> foo(11)     #p1=11,其它的參數爲默認賦值
p1==> 11
p2==> 22
p3==> 33
>>> foo(11, 222)     #按照順序,p2=222, p3依舊維持原默認值
p1==> 11
p2==> 222
p3==> 33
>>> foo(11, 222, 333)  #按順序賦值
p1==> 11
p2==> 222
p3==> 333

>>> foo(11, p2=122)
p1==> 11
p2==> 122
p3==> 33

>>> foo(p2=122)     #p1沒有默認值,必需要賦值的,不然報錯
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: foo() takes at least 1 argument (1 given)

def foo(*args)

這種方式適合於不肯定參數個數的時候,在參數args前面加一個*

>>> def foo(*args): 
...     print args
... 
>>> foo("qiwsir.github.io")
('qiwsir.github.io',)
>>> foo("qiwsir.github.io","python")
('qiwsir.github.io', 'python')

def foo(**args)

這種方式跟上面的區別在於,必須接收相似arg=val形式的。

>>> def foo(**args):    
...     print args
... 

>>> foo(1,2,3)   
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 0 arguments (3 given)

>>> foo(a=1,b=2,c=3)
{'a': 1, 'c': 3, 'b': 2}

特殊函數

lambda

# !/usr/bin/env python
#coding=utf-8

def add(x,y = 3):
    return x + y

ret = add(5)
print ret

lam = lambda x : x + 3
ret = lam(5)
print ret

lam = lambda x,y : x + y
ret = lam(5,5)
print ret

8
8
10

lambda函數的使用方法:

  • lambda後面直接跟變量;

  • 變量後面是冒號;

  • 冒號後面是表達式,表達式計算結果就是本函數的返回值;

lambda函數不能包含太多的命令,包含的表達式不能超過一個,不要試圖向lambda函數中塞入太多的東西,若是須要更復雜的東西,應該定義一個普通的函數。

map

# !/usr/bin/env python
#coding=utf-8

def add(x,y = 3):
    return x + y

numbers = range(9)
print numbers

ret = map(add, numbers) #只引用函數名便可
print ret

ret = map(lambda x : x + 4, numbers) #
print ret

ret = [x + 4 for x in numbers] #列表解析的方式實現
print ret

map()是Python的一個內置函數,它的基本樣式是:
map(fun,seq)

func是一個函數,seq是一個序列對象。在執行的時候,序列對象中的每一個對象,按照從左到右的順序依次被取出來,塞入到func函數裏面,並將func的返回值依次存到一個列表中。

reduce

reduce()是橫着逐個元素進行運算

# !/usr/bin/env python
#coding=utf-8

def add(x,y): #連續相加
    return x + y

def mul(x,y): #連續相乘
    return x * y

numbers = range(9)
print numbers

ret = reduce(add, numbers) 
print ret

ret = reduce(mul, numbers) 
print ret

[0, 1, 2, 3, 4, 5, 6, 7, 8]
36
0

filter

# !/usr/bin/env python
#coding=utf-8

numbers = range(-5,5)
print numbers

ret = filter(lambda x : x > 0, numbers) #過濾掉x < 0的數
print ret

ret = [x for x in numbers if x > 0]
print ret

ret = filter(lambda c : c != 'i', "liuguoquan") #過濾掉字符i
print ret

練習

求解一元二次方程

# !/usr/bin/env python
#coding=utf-8

"""
 求解一元二次方程
 
"""

from __future__ import division
import math

def quadratic_equation(a,b,c):
    delta = b * b - 4 * a * c
    if delta < 0:
        return False
    elif delta == 0:
        return -(b / (2 * a))
    else:
        sqrt_delat = math.sqrt(delta)
        x1 = (-b + sqrt_delat) / (2 * a)
        x2 = (-b - sqrt_delat) / (2 * a)
        return x1,x2

if __name__ == "__main__":
    print "a quadratic equation: x^2 + 2x + 1 = 0"
    coefficients = (1,2,1)
    roots = quadratic_equation(*coefficients)
    if roots:
        print "the result is: ",roots
    else:
        print "this equation has no solution"
        
a quadratic equation: x^2 + 2x + 1 = 0
the result is:  -1.0

統計考試成績

# !/usr/bin/env python
#coding=utf-8

"""
 統計考試成績
 
"""

from __future__ import division
import math

def average_score(scores):
    """
        統計平均分
    """
    score_values = scores.values()
    sum_scores = sum(score_values)
    average = sum_scores / len(score_values)
    return average

def sorted_score(scores):
    """
        對成績從高到低排序呢
    """
    score_list = [(scores[k],k) for k in scores]  #將鍵-值互換位置 score_list是列表,裏面的元素是一個元組
    sort_lst = sorted(score_list,reverse = True)
    return [(i[1],i[0]) for i in sort_lst] #將鍵-值互換位置

def max_score(scores):
    """
        成績最高的姓名和分數
    """
    lst = sorted_score(scores)
    max_score = lst[0][1]
    return [(i[0],i[1]) for i in lst if i[1] == max_score]

def min_scroe(scores):
    """
        成績最低的姓名和分數
    """
    lst = sorted_score(scores)
    min_score = lst[len(lst) - 1][1]
    return [(i[0],i[1]) for i in lst if i[1] == min_score]

if __name__ == "__main__":
    scores = {"google":98,"facebook":99,"baidu":52,"alibab":80,"yahoo":49,"android":76,"apple":99,"amazon":99}
    
    ret = average_score(scores) #平均分
    print "average is: ",ret

    ret = sorted_score(scores) #成績表
    print "list of scores is: ",ret
    
    ret = max_score(scores) #學霸們
    print "學霸是: ",ret
    
    ret = min_scroe(scores) #學渣
    print "學渣是: ",ret

average is:  81.5
list of scores is:  [('facebook', 99), ('apple', 99), ('amazon', 99), ('google', 98), ('alibab', 80), ('android', 76), ('baidu', 52), ('yahoo', 49)]
學霸是:  [('facebook', 99), ('apple', 99), ('amazon', 99)]
學渣是:  [('yahoo', 49)]

找質數

質數又稱素數,指在大於1的天然數中,除了1和此整數自身外,沒法被其餘天然整數整除的數(也可定義爲只有1和自己兩個因數的數)

# !/usr/bin/env python
#coding=utf-8

"""
尋找質數
"""
import math

def is_prime(n):
    """
    判斷一個數是不是質數
    """
    if n <=1:
        return False
    for i in range(2,int(math.sqrt(n) + 1)):
        if n % i == 0:
            return False
        return True

if __name__ == "__main__":
    
    primes = [i for i in range(2,100) if is_prime(i)]
    print primes

[5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]

編寫函數的注意事項

  • 儘可能不要使用全局變量

  • 若是參數是可變數據類型,則在函數內不要修改它

  • 每一個函數的功能和目的要單一,不要一個函數試圖作不少事情

  • 函數的代碼行數儘可能少

  • 函數的獨立性越強越好,不要跟其餘的外部東西產生關聯

相關文章
相關標籤/搜索