標籤:python 遞迴 切片
遞迴函式 ------- 在函數內部可以調用自身本身的函數
定義一個計算階乘的函數fact(n):
fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n
函數可以寫為:
>>> def fact(n): if n==1: return 1 return n*fact(n-1)>>> fact(1)1>>>fact(5)120>>> fact(100)93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
如果我們計算 fact(5),可以根據函數定義看到計算過程如下:
===> fact(5)===> 5 * fact(4)===> 5 * (4 * fact(3))===> 5 * (4 * (3 * fact(2)))===> 5 * (4 * (3 * (2 * fact(1))))===> 5 * (4 * (3 * (2 * 1)))===> 5 * (4 * (3 * 2))===> 5 * (4 * 6)===> 5 * 24===> 120
遞迴函式的優點是定義簡單,邏輯清晰。理論上,所有的遞迴函式都可以寫成迴圈的方式,但迴圈的邏輯不如遞迴清晰。
使用遞迴函式需要注意防止棧溢出。在電腦中,函數調用是通過棧(stack)這種資料結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴調用的次數過多,會導致棧溢出。可以試試fact(1000):
>>> fact(1000)Traceback (most recent call last): File "<pyshell#40>", line 1, in <module> fact(1000) File "<pyshell#33>", line 4, in fact return n*fact(n-1) File "<pyshell#33>", line 4, in fact return n*fact(n-1) File "<pyshell#33>", line 4, in fact return n*fact(n-1) 。。。 File "<pyshell#33>", line 4, in fact return n*fact(n-1) File "<pyshell#33>", line 2, in fact if n==1:RuntimeError: maximum recursion depth exceeded in comparison
切片
取一個list或tuple的部分元素:
(1):
直接通過索引取值
>>> l=[‘xaioming‘,‘zhangsan‘,‘wangwu‘,‘xiaoxin‘,‘xaiohua‘]>>> [l[0],l[1],l[2]][‘xaioming‘, ‘zhangsan‘, ‘wangwu‘]
(2):
通過迴圈取值
>>> r=[]>>> n=3>>> for i in range(n): r.append(l[i])
>>> r[‘xaioming‘, ‘zhangsan‘, ‘wangwu‘]
(3):
通過切片:
>>> l[0:3][‘xaioming‘, ‘zhangsan‘, ‘wangwu‘]
l[0:3] 表示從索引0開始,知道索引3為止,但不包括索引3.即索引0,1,2,正好是3個元素。
如果第一個索引是0,還可以省略:
>>> l[:3][‘xaioming‘, ‘zhangsan‘, ‘wangwu‘]
也可以從索引1開始,取出2個元素出來:
>>> l[1:3][‘zhangsan‘, ‘wangwu‘]
也可以倒數切片:
>>> l[-1]‘xaiohua‘
>>> l[-2:][‘xiaoxin‘, ‘xaiohua‘]
建立一個0-99的數列:
>>> L = list(range(100))>>> L[0, 1, 2, 3, ..., 99]
取前十個元素:
>>> L[:10][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
後十個元素:
>>> L[-10:][90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
前11-20:
>>> L[11:20][11, 12, 13, 14, 15, 16, 17, 18, 19]
前10個數,,每兩個取一個:
>>> L[0:10:2][0, 2, 4, 6, 8]
所有數,每5個取一個:
>>> L[0:100:5][0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]>>> L[::5][0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
>>> L[:][0, 1, 2, 3, ..., 99]
tuple也是一種list ,只是tuple不可變。tuple也可以切片:
>>> (0,1,2,3,4,5)[:3](0, 1, 2)
字串 ‘xxxxx’也可以看做一個list,每個元素就是一個字元。因此,字串也可以切片
>>> ‘ABCDEFGHIKLMNOPQRST‘[:3]‘ABC‘>>> ‘ABCDEFGHIKLMNOPQRST‘[::2]‘ACEGILNPRT‘
迭代
給定一個list或tuple,我們通過for迴圈來遍曆這個list或tuple,這種遍曆我們稱為 迭代(lteration)。
Python的for迴圈不僅可以用在list或tuple上,還可以作用在其他可迭代對象上。
list這種資料類型雖然有下標,但很多其他資料類型是沒有下標的,但是,只要是可迭代對象,無論有無下標,都可以迭代,比如dict就可以迭代:
>>> d = {‘a‘:1,‘b‘:2,‘c‘:3}>>> for key in d: print(key) cba
因為dict的儲存不是按照list的方式順序排列,所以,迭代出的結果順序很可能不一樣。
預設情況下,dict 迭代的是 key 。如果要迭代 value,可以用
for value in d.values()
如果要同時迭代key和value,可以用
for k,v in d.items()
由於字串也是可迭代對象。因此,也可以作用與 for 迴圈:
>>> for ch in ‘ABC‘: print(ch) ABC
如何判斷一個對象是可迭代對象呢?方法是通過collections模組的Iterable類型判斷:
>>> from collections import Iterable>>> isinstance(‘abc‘,Iterable)True>>> isinstance([1,2,3],Iterable)True>>> isinstance(123,Iterable)False
如果要對list實作類別似於 c 語言 那樣的下標迴圈怎麼辦?Python內建的 enumerate 函數 可以把一個list變成索引-元素對,這樣就可以在 for 迴圈中同時迭代索引和元素本身:
>>> for i,value in enumerate([‘A‘,‘B‘,‘C‘]): print(i,value) 0 A1 B2 C
上面的for迴圈裡,同時引用了兩個變數,在Python裡是很常見的,比如下面的代碼:
>>> for x,y in [(1,1),(2,2),(3,3)]: print(x,y) 1 12 23 3
本文出自 “啟思·朝聖者” 部落格,請務必保留此出處http://dearch.blog.51cto.com/10423918/1761631
據廖雪峰python3教程----python學習第九天