Python基礎教程第2版 6:抽象 http://blog.chinaunix.net/uid-21142030-id-5676171.html
抽象與結構,事件流程
建立函數是組織程式的關鍵.def
使用函數改變資料結構(比如list,dict)是将程式抽象化的好方法.
函數定義中的參數是形參
函數調用中的參數是實參
函數通過參數擷取值.
函數内部作用域修改參數值不會影響外部值.
抽象的要點是隐藏更新時的煩瑣細節.
函數隻能修改參數對象本身.
一個将姓名查詢添加程式
點選(此處)折疊或打開
- #!/usr/bin/env python
- #-*- coding:utf-8 -*-
- '''
- 斐波那契數列:初始為0,1,清單中的一個數字是前兩個元素的和
- num=int(raw_input('請輸入要計算的斐波那契數列的數目:'))
- def fibs(num):
- '文檔字元串 fibs.__doc__檢視'
- result=[0,1]
- for i in range(num-2):
- result.append(result[-2]+result[-1])
- return result
- print fibs(num)
- #初始化資料庫
- def initdata(data):
- data['first']={}
- data['middle']={}
- data['last']={}
- storage={}
- initdata(storage)
- me='eric lei wang'
- you='talen tf HAO'
- her='mei liu'
- #查詢方法
- def lookup(database,lable,name):
- result=database[lable].get(name)
- #錄入資料庫
- def store(database,username):#把使用者存入資料庫中
- #1.分割使用者名
- names=username.split()
- lables=['first','middle','last']
- if len(names)==2:
- names.insert(1,'')
- for lable,name in zip(lables,names):
- #判斷是否已經存在
- people=lookup(database,lable,name)
- if people:
- #如果清單中有值,直接添加
- people.append(username)
- else:
- #如果清單沒有值,新建立,注意,這裡生成的是清單.
- database[lable][name]=[username]
- store(storage,me)
- store(storage,you)
- store(storage,her)
- print storage
關鍵字參數和預設值
位置參數與關鍵字參數是可以聯合使用的.除非完全清楚程式的功能和參數的意義,否則應該避免混合使用.
使用*收集任意多的參數,傳回數組.
使用**收集任意多的關鍵字參數,傳回字典.
修改一下上面的程式,支援多個名字同時錄入
- def store(database,*usernames):#把使用者存入資料庫中
- for username in usernames:
- names=username.split()
- lables=['first','middle','last']
- if len(names)==2:
- names.insert(1,'')
- for lable,name in zip(lables,names):
- #判斷是否已經存在
- people=lookup(database,lable,name)
- if people:
- #如果清單中有值,直接添加
- people.append(username)
- else:
- #如果清單沒有值,新建立,注意,這裡生成的是清單.
- database[lable][name]=[username]
- store(storage,me,you)
點選(此處)折疊或打開
- 請輸入要計算的斐波那契數列的數目:11
- [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
- {'middle': {'tf': ['talen tf HAO', 'talen tf HAO'], 'lei': ['eric lei wang', 'eric lei wang'], '': ['mei liu']}, 'last': {'liu': ['mei liu'], 'wang': ['eric lei wang', 'eric lei wang'], 'HAO': ['talen tf HAO', 'talen tf HAO']}, 'first': {'mei': ['mei liu'], 'eric': ['eric lei wang', 'eric lei wang'], 'talen': ['talen tf HAO', 'talen tf HAO']}}
- 參數練習
- def story(**kwds):
- return 'Once upon a time,there was a %(job)s called %(name)s.' % kwds
- def power(x,y,*others):
- if others:
- print 'Received redundant parameters:',others
- return pow(x,y)
- def interval(start, stop=None,step=1):
- '列印指定範圍的數字'
- if stop is None:
- start,stop=0,start
- result=[]
- while start stop:
- result.append(start)
- start+=step
- print story(job='ttserver',name='workhard')
- print story(name='mile',job='assssfsffa')
- params={'job':'job1','name':'nameserver'}
- print story(**params)
- print power(2,3)
- print power(y=4,x=5)
- params=(5,)*2
- print power(*params)
- print power(3,3,'talen')
- print interval(10)
- print interval(1,5)
- print interval(3,12,4)
- print power(*interval(3,7))
- Once upon a time,there was a ttserver called workhard.
- Once upon a time,there was a assssfsffa called mile.
- Once upon a time,there was a job1 called nameserver.
- 8
- 625
- 3125
- Received redundant parameters: ('talen',)
- 27
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- [1, 2, 3, 4]
- [3, 7, 11]
- Received redundant parameters: (5, 6)
- 81
嵌套函數傳回内嵌套在内的函數是帶着傳回的函數的環境和相關局部變量一起傳回的,是以可以調用外部函數時附加變量值給傳回的函數.
def A(a):
def B(b):
a+b
return B
A(a)(b)或
C=A(a)
C(b)
C是A的傳回函數即C=B
遞歸
函數調用自身的行為就是遞歸
遞歸必須以最小可能性為結束
- #-*- coding:utf-8 -*-
- def factorial(n):
- result=n
- for i in range(1,n):
- result*=i
- print result
- return result
- print('最終結果是%s' %factorial(5))
- def factorial2(n):
- if n == 1 :
- return 1
- else:
- return n*factorial2(n-1)
- print('階乘的結果是%s' % factorial2(6))
- def power(x,n):
- result=x
- if n == 0:
- return result * power(x,n-1)
- print(power(3,3))
- 5
- 10
- 30
- 120
- 最終結果是120
- 階乘的結果是720
- 27
二進制查找
如果不自己寫,标準庫有bisect子產品可以有效實作二進制查找.
宇宙中的粒子數約為10的87次方,隻要290個問題就能分辨它們.
- #二進制運算
- #元素:序列,數,位置,範圍最小值位置,最大值位置
- def search(sequence,number,lower=0,upper=None):
- #先判斷是否在序列中
- if number in sequence:
- if upper is None:
- upper=len(sequence)-1
- if lower==upper:
- return upper
- else:
- #定義中間數,不能
- middle=(lower+upper)//2
- #判斷在哪一邊
- if number > sequence[middle]:
- return search(sequence,number,middle+1,upper)
- return search(sequence,number,lower,middle)
- return '沒有這個數字'
- seq=[34,67,8,123,4,100,95]
- seq.sort()
- print seq
- print('數字位于%s' % search(seq,34))
- print('數字位于%s' % search(seq,55))
- print('數字位于%s' % search(seq,95))
- [4, 8, 34, 67, 95, 100, 123]
- 數字位于2
- 數字位于沒有這個數字
- 數字位于4