第六章 抽象

6.1 懶惰即美德

6.2 抽象和結構

6.3 創建函數

def:定義函數
內建函數callable:可以用來判斷函數是否可調用

>>> import math
>>> x=1
>>> y=math.sqrt
>>> callable(x)
False
>>> callable(y)
True

6.3.1 文檔化函數

兩種方式:註釋、字符串
doc:可以查看函數說明
或者使用help:獲得相關信息

>>> def addition(x,y):
...     'Conputer the sum of x and y'
...     #hello
...     return x+y
... 
>>> addition.__doc__
'Conputer the sum of x and y'
>>> help(addition)
Help on function addition in module __main__:

addition(x, y)
    Conputer the sum of x and y

6.3.2 並非真正的函數

不管有沒有return,python的函數都會返回值,至少會返回None

6.4 參數魔法

6.4.1 值從哪裏來

實參和形參

6.4.2 我能改變參數嗎

1.爲什麼要修改參數

例子:名字的存取

def init(data):
    data['first']={}
    data['middle']={}
    data['last']={}

def lookup(data,label,name):
    return data[label].get(name)

def store(data,full_name):
    names=full_name.split()
    if len(names)==2:names.insert(1,'')
    labels='first','middle','last'

    for label,name in zip(labels,names):
        people=lookup(data,label,name)
        if people:
            people.append(full_name)
        else:
            data[label][name]=[full_name]

Mynames={}
init(Mynames)

store(Mynames,'Robin Hood')
store(Mynames,'Robin Loksy')
store(Mynames,'Mr. Gumby')

print lookup(Mynames,'middle','')

2.如果我的參數不可變呢
可使用列表或者函數返回再賦值

6.4.3 關鍵字參數和默認值

在調用函數我們可以使用(參數名+值)來回避位置問題

def hello(greeting,name):
    print greeting+','+name
hello(name='jack!',greeting='hello')#參數不受前後順序的限制

還可以給參數設置默認值

6.4.4 收集參數

帶*號的參數:收集剩餘位置的參數放在一個元組
如果要處理關鍵字參數使用**:放在字典

def print_params(x,y,z=3,*pospar,**keypar):
    print x,y,z
    print pospar
    print keypar 
print_params(1,2,3,5,6,7,foo=1,bar=2)

1 2 3
(5, 6, 7)
{'foo': 1, 'bar': 2}

6.4.5 參數收集的逆過程

params={'name':'Sir Robin','greeting':'Well met'}
hell(**params)

元組或列表用:* 字典用:**

6.4.6 練習

6.5 作用域

globals:返回全局變量值
locals:返回局部變量的字典
vars:返回全局變量的字典

嵌套作用域:

def multiplier(factor):
    def multiplyByFactor(number):
        return number*factor
    return multiplyByFactor
>>>double=multiplier(2)
>>>double(5)
>>>10

外層循環返回裏層循環,但是並沒有調用,它“帶着”它的環境

6.6 遞歸

6.6.1 兩個經典:階乘和冪

#n的階乘
def factorial(n):
    if n==1:
        return 1
    else: return n*factorial(n-1)
#二分查找
def search(sequence,number,lower,upper):
    if lower==upper:
        assert number==sequence[upper]#檢查是否相等,如果這個時候還不相等則找不到,幹掉程序,相等返回upper
        return upper
    else:
        middle=(lower+upper)//2
        if number>sequence[middle]:
            return search(sequence,number,middle+1,upper)
        else:
            return search(sequence,number,lower,middle)

函數式編程:
map、filter、reduce
map和filter可以輕易被列表推導式代替,基本沒什麼大的用處,reduce雖然不能輕易被替代,但是很少用到

>>> number=[1,2,3,4,5,6]
>>> reduce(lambda x,y:x+y,number)
21

首先從列表裏取前兩個數,然後執行x+y,然後將結果當成x,再從列表裏取出一個數當做y,直到列表的數據全被處理

本章新函數

map(func,seq[,seq,…]):對序列中的每個元素應用函數
filter(func,seq):返回其函數爲真的元素的列表
reduce(func,seq[,initial]):等同於func(func(seq[0].seq[1]),seq[2]….)
sum(seq):列表求和
apply(func[,args[,kwargs]]):調用函數,參數從元組或字典裏取

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章