1. 程式人生 > >Python入門基礎之函數、切片

Python入門基礎之函數、切片

[1] href 原來 告訴 官方 tro art range 方便

Python之函數


Python不但能非常靈活地定義函數,而且本身內置了很多有用的函數,可以直接調用。

Python之調用函數


Python內置了很多有用的函數,我們可以直接調用。

要調用一個函數,需要知道函數的名稱和參數,比如求絕對值的函數 abs,它接收一個參數。

可以直接從Python的官方網站查看文檔:

http://docs.python.org/2/library/functions.html#abs

也可以在交互式命令行通過 help(abs) 查看abs函數的幫助信息。

調用 abs 函數:

>>> abs(100)
100
>>> abs(-20)
20 >>> abs(12.34) 12.34

調用函數的時候,如果傳入的參數數量不對,會報TypeError的錯誤,並且Python會明確地告訴你:abs()有且僅有1個參數,但給出了兩個:

>>> abs(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)

如果傳入的參數數量是對的,但參數類型不能被函數所接受,也會報TypeError的錯誤,並且給出錯誤信息:str是錯誤的參數類型:

>>> abs(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): str

而比較函數 cmp(x, y) 就需要兩個參數,如果 x<y,返回 -1,如果 x==y,返回 0,如果 x>y,返回 1:

>>> cmp(1, 2)
-1
>>> cmp(2, 1)
1
>>> cmp(3, 3)
0

Python內置的常用函數還包括數據類型轉換函數,比如 int()函數可以把其他數據類型轉換為整數:

>>> int(123)
123
>>> int(12.34)
12

str()函數把其他類型轉換成 str:

>>> str(123)
123
>>> str(1.23)
1.23

sum()函數接受一個list作為參數,並返回list所有元素之和。請計算 1*1 + 2*2 + 3*3 + ... + 100*100。

L = []
x = 1
while x <= 100:
    L.append(x * x)
    x = x + 1
print sum(L)

Python之編寫函數


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

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

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

請註意,函數體內部的語句在執行時,一旦執行到return時,函數就執行完畢,並將結果返回。因此,函數內部通過條件判斷和循環可以實現非常復雜的邏輯。

如果沒有return語句,函數執行完畢後也會返回結果,只是結果為 None。

return None可以簡寫為return。

Python函數之返回多值


數可以返回多個值嗎?答案是肯定的。

比如在遊戲中經常需要從一個點移動到另一個點,給出坐標、位移和角度,就可以計算出新的坐標:

# math包提供了sin()和 cos()函數,我們先用import引用它:

import math
def move(x, y, step, angle):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

這樣我們就可以同時獲得返回值:

>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print x, y
151.961524227 70.0

但其實這只是一種假象,Python函數返回的仍然是單一值:

>>> r = move(100, 100, 60, math.pi / 6)
>>> print r
(151.96152422706632, 70.0)

用print打印返回結果,原來返回值是一個tuple!

但是,在語法上,返回一個tuple可以省略括號,而多個變量可以同時接收一個tuple,按位置賦給對應的值,所以,Python的函數返回多值其實就是返回一個tuple,但寫起來更方便。

Python之遞歸函數


在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數。

舉個例子,我們來計算階乘 n! = 1 * 2 * 3 * ... * n,用函數 fact(n)表示,可以看出:

def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)

遞歸函數的優點是定義簡單,邏輯清晰。理論上,所有的遞歸函數都可以寫成循環的方式,但循環的邏輯不如遞歸清晰。

使用遞歸函數需要註意防止棧溢出。在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出。可以試試計算 fact(10000)。

Python之定義默認參數


定義函數的時候,還可以有默認參數。

例如Python自帶的 int() 函數,其實就有兩個參數,我們既可以傳一個參數,又可以傳兩個參數:

>>> int(123)
123
>>> int(123, 8)
83

int()函數的第二個參數是轉換進制,如果不傳,默認是十進制 (base=10),如果傳了,就用傳入的參數。

可見,函數的默認參數的作用是簡化調用,你只需要把必須的參數傳進去。但是在需要的時候,又可以傳入額外的參數來覆蓋默認參數值。

我們來定義一個計算 x 的N次方的函數:

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

假設計算平方的次數最多,我們就可以把 n 的默認值設定為 2:

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

這樣一來,計算平方就不需要傳入兩個參數了:

>>> power(5)
25

由於函數的參數按從左到右的順序匹配,所以默認參數只能定義在必需參數的後面:

# OK:
def fn1(a, b=1, c=2):
    pass
# Error:
def fn2(a=1, b):
    pass

Python之定義可變參數


如果想讓一個函數能接受任意個參數,我們就可以定義一個可變參數:

def fn(*args):
    print args

可變參數的名字前面有個 * 號,我們可以傳入0個、1個或多個參數給可變參數:

>>> fn()
()
>>> fn(a)
(a,)
>>> fn(a, b)
(a, b)
>>> fn(a, b, c)
(a, b, c)

可變參數也不是很神秘,Python解釋器會把傳入的一組參數組裝成一個tuple傳遞給可變參數,因此,在函數內部,直接把變量 args 看成一個 tuple 就好了。

定義可變參數的目的也是為了簡化調用。假設我們要計算任意個數的平均值,就可以定義一個可變參數:

def average(*args):
    sum = 0.0
    if len(args) == 0:
        return sum
    for x in args:
        sum = sum + x
    return sum / len(args)

這樣,在調用的時候,可以這樣寫:

>>> average()
0
>>> average(1, 2)
1.5
>>> average(1, 2, 2, 3, 4)
2.4

對list進行切片


取一個list的部分元素是非常常見的操作。比如,一個list如下:

>>> L = [Adam, Lisa, Bart, Paul]

取前3個元素,應該怎麽做?

笨辦法:

>>> [L[0], L[1], L[2]]
[Adam, Lisa, Bart]

之所以是笨辦法是因為擴展一下,取前N個元素就沒轍了。

取前N個元素,也就是索引為0-(N-1)的元素,可以用循環:

>>> r = []
>>> n = 3
>>> for i in range(n):
...     r.append(L[i])
... 
>>> r
[Adam, Lisa, Bart]

對這種經常取指定索引範圍的操作,用循環十分繁瑣,因此,Python提供了切片(Slice)操作符,能大大簡化這種操作。

對應上面的問題,取前3個元素,用一行代碼就可以完成切片:

>>> L[0:3]
[Adam, Lisa, Bart]

L[0:3]表示,從索引0開始取,直到索引3為止,但不包括索引3。即索引0,1,2,正好是3個元素。

如果第一個索引是0,還可以省略:

>>> L[:3]
[Adam, Lisa, Bart]

也可以從索引1開始,取出2個元素出來:

>>> L[1:3]
[Lisa, Bart]

只用一個 : ,表示從頭到尾:

>>> L[:]
[Adam, Lisa, Bart, Paul]

因此,L[:]實際上復制出了一個新list。

切片操作還可以指定第三個參數:

>>> L[::2]
[Adam, Bart]

第三個參數表示每N個取一個,上面的 L[::2] 會每兩個元素取出一個來,也就是隔一個取一個。

把list換成tuple,切片操作完全相同,只是切片的結果也變成了tuple。

例子:

range()函數可以創建一個數列:

>>> range(1, 101)
[1, 2, 3, ..., 100]

請利用切片,取出:

1. 前10個數;
2. 3的倍數;
3. 不大於50的5的倍數。

L = range(1, 101)

print L[:10]
print L[2::3]
print L[4:50:5]

倒序切片


對於list,既然Python支持L[-1]取倒數第一個元素,那麽它同樣支持倒數切片,試試:

>>> L = [Adam, Lisa, Bart, Paul]

>>> L[-2:]
[Bart, Paul]

>>> L[:-2]
[Adam, Lisa]

>>> L[-3:-1]
[Lisa, Bart]

>>> L[-4:-1:2]
[Adam, Bart]

記住倒數第一個元素的索引是-1。倒序切片包含起始索引,不包含結束索引。

註意:-4要在-1前面;同樣地,-3也得在-1前面。即使是倒序切片,排倒數第一的依舊在後面。

對字符串切片


字符串 ‘xxx‘和 Unicode字符串 u‘xxx‘也可以看成是一種list,每個元素就是一個字符。因此,字符串也可以用切片操作,只是操作結果仍是字符串:

>>> ABCDEFG[:3]
ABC
>>> ABCDEFG[-3:]
EFG
>>> ABCDEFG[::2]
ACEG

在很多編程語言中,針對字符串提供了很多各種截取函數,其實目的就是對字符串切片。Python沒有針對字符串的截取函數,只需要切片一個操作就可以完成,非常簡單。

例子:

>>> abc.upper()
ABC

但它會把所有字母都變成大寫。請設計一個函數,它接受一個字符串,然後返回一個僅首字母變成大寫的字符串。

提示:利用切片操作簡化字符串操作。

def firstCharUpper(s):
    return s[0].upper() + s[1:]

參考慕課網課程:http://www.imooc.com/learn/177

Python入門基礎之函數、切片