1. 程式人生 > >python學習筆記03-python函數語言程式設計

python學習筆記03-python函數語言程式設計

1. 高階函式

1. 高階函式基礎

變數可以指向函式
函式名也是變數
高階函式允許傳入函式 

#!/usr/bin/env python
#將函式賦值給變數
A = abs
print A(-10)
#匯入__builtin__模組
import __builtin__
#改變abs變數的指向
__builtin__.abs = 20
#輸出abs變數
print abs
abs = 30
print abs
abs = A
print abs(-10)
#定義一個高階函式,入參是函式
def add(x,y,func):
        return func(x) + func(y)
#呼叫高階函式
print add(-10,3,abs)

2. map/reduce

map()函式接收兩個引數,一個是函式,一個是序列,map將傳入的函式依次作用到序列的每個元素,並把結果作為新的list返回。
reduce()函式接收兩個引數,一個是函式,一個是序列,reduce把前面兩個資料通過傳入的函式運算得出的結果再與後面一個數據使用傳入的函式進行運算,最終返回結果。 

#!/usr/bin/env python
def add(x):
        return x + 2
#使用map,讓list裡面每個元素都執行一次add函式,之後返回一個新的list
print map(add,[1,2,3])
def sum(x,y):
        return x + y
#使用reduce,先取list裡面的第一、二個元素,執行一次傳入的函式。得到的結果再與後面的元素結合成引數,執行一次函式,依此類推,最終後返回結果
print reduce(sum,[1,2,3])
#使用reduce和map,定義了一個字串轉換數字的函式
def str2int(s):
        def fn(x,y):
                return x * 10 + y
        def char2num(s):
                return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
        return reduce(fn,map(char2num,s))
print str2int('1314')

3. filter

接收一個過濾器,用於過濾序列中的元素,只保留過濾器認可的元素
當過濾器返回False時,將刪除掉序列中的元素 

#!/usr/bin/env python
#定義一個過濾器,將所有奇數過濾出來
def is_odd(n):
        return n % 2 == 1
print filter(is_odd,[1,2,3,4])

4. sorted

接收一個比較器,對序列進行排序 

#!/usr/bin/env python
L = [36,5,12,9,21]
print sorted(L)
#定義一個比較器
def reversed_cmp(x,y):
        if x > y:
                return -1
        if x < y:
                return 1
        return 0
print sorted(L,reversed_cmp)
#定義一個忽略大小寫的字串比較器
def cmp_ignore_case(s1,s2):
        u1 = s1.upper()
        u2 = s2.upper()
        if u1 < u2:
                return -1
        if u1 > u2:
                return 1
        return 0
print sorted(['bob','about','Zoo'],cmp_ignore_case);

2.函式作為返回值

#!/usr/bin/env python
def lazy_sum(*args):
        #定義一個求和函式,返回給呼叫者
        def sum():
                s = 0
                for n in args:
                        s = s + n
                return s
        return sum
#求和沒有立即執行,而只是返回了一個函式
f = lazy_sum(1,2,3)
#當呼叫f()時,求和才真正執行
print f()

3.閉包

#!/usr/bin/env python
def count():
        fs = []
        for i in range(1,4):
                def f1(x):
                        #定義一個閉包函式
                        def f2():
                                return x * x
                        return f2
                fs.append(f1(i))
        return fs
f1,f2,f3 = count()
print f1()
print f2()
print f3()

4. 匿名函式lambda

注意,冒號前面的表示引數

#!/usr/bin/env python
#定義一個匿名函式,並賦值給了變數f
f = lambda x,y: x + y
print f(1,2)
#定義一個匿名函式,並傳給了map函式
print map(lambda x: x + 1,[1,2,3])

5. 裝飾器decorator

函式有一個name屬性,可以拿到函式的名字
Python內建的functools.wraps可以把原始函式的屬性複製到新定義的函式中 

#!/usr/bin/env python
import functools
#定義一個不帶引數的裝飾器,用於輸出日誌
def log(func):
        @functools.wraps(func)
        def wrapper(*args,**kw):
                print 'call %s():' % func.__name__
                return func(*args,**kw)
        return wrapper
#註明此函式需要使用裝飾器
@log
def now():
        print '2015-12-12'
#呼叫now函式,會輸出日誌
now()
print '\n'
#定義一個帶引數(有預設引數)的裝飾器,用於輸出日誌
def log2(text='--call--'):
        def decorator(func):
                @functools.wraps(func)
                def wrapper(*args,**kw):
                        print '%s %s():' % (text,func.__name__)
                        return func(*args,**kw)
                return wrapper
        return decorator
#註明now2函式需要使用裝飾器
@log2('execute')
def now2():
        print '2015-12-12'
#呼叫now2函式
now2()
#註明now3函式需要使用裝飾器(使用裝飾器的預設引數)
@log2()
def now3():
        print '2015-12-12'
#呼叫now3函式
now3()

6. 偏函式Partial function

當函式的引數個數太多,可以使用functools.partial,建立一個新函式,這個新函式可以固定原函式的部分引數,從而在呼叫時更簡單。

#!/usr/bin/env python
import functools
#建立一個偏函式,固定引數base的值為2
int2 = functools.partial(int,base=2)
#呼叫偏函式
print int2('100')
def max(x,y):
        if x > y:
                return x
        return y
print max(22,10)
#定義一個偏函式,固定引數x為22
max2 = functools.partial(max,22)
#呼叫偏函式,此時,x已經被固定為22,固只需要傳入y的值為10
print max2(10)