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]]):調用函數,參數從元組或字典裏取