函式式程式設計就是封裝成乙個個函式,一次呼叫來完成複雜任務。
函式式程式設計的乙個特點是,允許把函式本身作為引數傳入另乙個函式,還允許返回乙個函式!
高階函式就是將函式的變數名作為引數傳入,內部再對該函式進行呼叫的函式。
乙個簡單的高階函式如下:
defadd(x, y, f):
return f(x) + f(y)
x ==> -5y ==> 6f ==>absf(x) + f(y) ==> abs(-5) + abs(6) ==> 11
>>> add(-5, 6, abs)11
python內建了map()、reduce()、filter()和sorted()等高階函式。
map()
函式接收兩個引數,乙個是函式,乙個是序列,map
將傳入的函式依次作用到序列的每個元素,並把結果作為新的list返回。
>>> deff(x):
...
return x *x
...>>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]
map()
作為高階函式,事實上它把運算規則抽象了,因此,我們不但可以計算簡單的f(x)=x2,還可以計算任意複雜的函式,比如,把這個list所有數字轉為字串:
>>> map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])['1', '
2', '
3', '
4', '
5', '
6', '
7', '
8', '
9']
>>> deffn(x, y):
...
return x * 10 +y
...>>> reduce(fn, [1, 3, 5, 7, 9])
13579
filter()函式是用於過濾序列的,傳入乙個函式和乙個序列。filter()
把傳入的函式依次作用於每個元素,然後根據返回值是true
還是false
決定保留還是丟棄該元素,如:
defnot_empty(s):
return s and
s.strip()
filter(not_empty, ['a
', '', '
b', none, '
c', ''])
#結果: ['a', 'b', 'c']
sorted()函式是用於對序列進行排序,傳入乙個序列和乙個預設函式為cmp的函式。只傳入序列時,進行預設排序,如下:
>>> sorted([36, 5, 12, 9, 21])[5, 9, 12, 21, 36]
傳入序列和函式時,依據傳入的函式進行排序,如下:
defreversed_cmp(x, y):
if x >y:
return -1
if x return 1
return 0
>>> sorted([36, 5, 12, 9, 21], reversed_cmp)[36, 21, 12, 9, 5]
乙個函式的返回值不是變數,而是函式。這種方式可以構成「閉包」,對程式有極大的應用,如裝飾器。
但是需要注意的是:返回函式不要引用任何迴圈變數,或者後續會發生變化的變數。
defcount():
fs =
for i in range(1, 4):
deff():
return i*i
return
fsf1, f2, f3 = count()
>>>f1()9>>>f2()
9>>>f3()
9
如果一定要引用迴圈變數的話,方法是再建立乙個函式,用該函式的引數繫結迴圈變數當前的值,無論該迴圈變數後續如何改變,已繫結到函式引數的值不變。
>>> defcount():
... fs =
...
for i in range(1, 4):
...
deff(j):
...
defg():
...
return j*j
...
return
g...
return
fs...
>>> f1, f2, f3 =count()
>>>f1()
1>>>f2()
4>>>f3()
9
當python中,傳入函式不需要顯式地定義時,就可以利用匿名函式直接帶入;同時,由於匿名函式沒有名字,不會出現函式名字衝突的情況。
匿名函式的格式是:lambda x: x * x
當希望在已有的函式基礎上增加一部分功能,但是又不想重新改函式時,就可以使用裝飾器,進行動態的修改,例如:對乙個函式增加日誌列印的功能。
deflog(func):
'call %s():
' % func.__name__
return func(*args, **kw)
@log
defnow():
'2013-12-25
'
>>>now()call now():
2013-12-25
另外,要改變列印內容時,用到3層套用,就是下面的情況:
import functools
def log(text):
def decorator(func):
@functools.wraps(func) # 裝飾後不改變原函式的內建屬性
print '%s %s():' % (text, func.__name__)
return func(*args, **kw)
return decorator
@log('execute')
defnow():
'2013-12-25
'
>>>now()execute now():
2013-12-25
對於已有的函式,如果有預設的引數值,但是我們最近常呼叫的是另乙個引數值時,可以使用偏函式,生成預設值為另乙個引數的新函式。
>>> importfunctools
>>> int2 = functools.partial(int, base=2)
>>> int2('
1000000')
64>>> int2('
1010101')
85
相當於:
def int2(x, base=2):return int(x, base)
注:本文為學習廖雪峰python入門整理後的筆記
Day6 遞迴函式
遞迴函式看的雲裡霧裡,廖雪峰大師給出的練習題我也沒搞懂,先mark下理解的,其他的後續再說 通過之前的學習已經知道,函式的內部是可以呼叫其他函式的,如果乙個函式在內部呼叫自身本身,那麼這個函式就是遞迴函式。定義乙個計算階乘n!的函式 n 1x2x3x4x xn,用函式來表示可以看出 jx n n 1...
程式設計之旅 Day6
1 劍指offer 面試題10 斐波那契數列 面試題17 列印從1到最大的n位數 2 leetcode 例1 鍊錶排序 例2 判斷鍊錶是否含有環 面試題10 斐波那契數列 題目描述 大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項 從0開始,第0項為0 n 39。思路 1...
Day 6 函式與模組
def函式名 引數列表 函式體 示例1 計算矩形面積 函式名 area 引數 width 和 height 返回值 width height def area width,height 1 return width height 必須引數,按順序傳入引數 其中,5,6 按順序傳入,預設傳入width...