Day 6 函式式程式設計

2022-08-09 02:21:11 字數 3847 閱讀 4478

函式式程式設計就是封裝成乙個個函式,一次呼叫來完成複雜任務。

函式式程式設計的乙個特點是,允許把函式本身作為引數傳入另乙個函式,還允許返回乙個函式!

高階函式就是將函式的變數名作為引數傳入,內部再對該函式進行呼叫的函式。

乙個簡單的高階函式如下:

def

add(x, y, f):

return f(x) + f(y)

x ==> -5y ==> 6f ==>abs

f(x) + f(y) ==> abs(-5) + abs(6) ==> 11

>>> add(-5, 6, abs)

11

python內建了map()、reduce()、filter()和sorted()等高階函式。

map()函式接收兩個引數,乙個是函式,乙個是序列,map將傳入的函式依次作用到序列的每個元素,並把結果作為新的list返回。

>>> def

f(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']

>>> def

fn(x, y):

...

return x * 10 +y

...>>> reduce(fn, [1, 3, 5, 7, 9])

13579

filter()函式是用於過濾序列的,傳入乙個函式和乙個序列。filter()把傳入的函式依次作用於每個元素,然後根據返回值是true還是false決定保留還是丟棄該元素,如:

def

not_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]

傳入序列和函式時,依據傳入的函式進行排序,如下:

def

reversed_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]

乙個函式的返回值不是變數,而是函式。這種方式可以構成「閉包」,對程式有極大的應用,如裝飾器。

但是需要注意的是:返回函式不要引用任何迴圈變數,或者後續會發生變化的變數。

def

count():

fs =

for i in range(1, 4):

deff():

return i*i

return

fsf1, f2, f3 = count()

>>>f1()

9>>>f2()

9>>>f3()

9

如果一定要引用迴圈變數的話,方法是再建立乙個函式,用該函式的引數繫結迴圈變數當前的值,無論該迴圈變數後續如何改變,已繫結到函式引數的值不變。

>>> def

count():

... 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

當希望在已有的函式基礎上增加一部分功能,但是又不想重新改函式時,就可以使用裝飾器,進行動態的修改,例如:對乙個函式增加日誌列印的功能。

def

log(func):

print

'call %s():

' % func.__name__

return func(*args, **kw)

@log

defnow():

print

'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():

print

'2013-12-25

'

>>>now()

execute now():

2013-12-25

對於已有的函式,如果有預設的引數值,但是我們最近常呼叫的是另乙個引數值時,可以使用偏函式,生成預設值為另乙個引數的新函式。

>>> import

functools

>>> 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...