聊一下條件控制和循環:
條件控制:
strBirth = input('please enter your birth:') birth = int(strBirth) if birth < 2000: print('You are after 00') elif birth < 2010: print('You are after 10') else: print('You are before 00')
當用戶從屏幕上輸入出生年份的時候,python接收的類型是字符串類型,所以在做判斷之前,先將strBirth轉換為int類型birth,然后再和整數進行比較。
elif 是else if 的縮寫,完全可以有多個elif
循環:有兩種循環,一種是for...in,另一種是while
for...in循環,依次把list或者tuple中的每一個元素迭代出來:
如計算1+2+...+100:
1 sum = 0 2 for i in range(101): 3 sum = sum + i
range():生成一個整數序列,從0開始。
while循環:只要條件滿足就繼續循環,條件不滿足時結束循環
如,計算100以內的奇數和
sum = 0 n = 99 while n > 0: sum = sum + n n = n-2
break:在循環中,break語句可以提前退出循環
continue: 在循環中,結束本次循環,開始下一輪的循環
這兩個語句通常都是配合着if語句使用
字典dict和無序不重復的集合set
字典dict:使用鍵值對(key-value)存儲,key必須是不可變對象,具有極快的查找速度
d = {'A':21,'B':{'C':2,'D':1}} 或 d = dict(A=21,B=dict(C=2,D=1))
所以取d['A'],為21
查看key是否在d中,兩種方法:
通過 in:
'A' in d: 返回True 或則 False
通過get():
d.get('A',value): value是自己指定的值,若d中不存在'A',返回value,默認value是None,若存在則返回'A'對應的值21
要刪除key,使用pop(key),對應的值也會一同被刪除
注意:dict內部存放的順序和key放入的順序無關
dict和list相比:
dict:查找和插入速度快、但是費內存空間(以空間換時間)
list:查找和插入的時間隨着元素的增加而逐漸增加,但是占內存小(以時間換空間)
set:
set和dict一樣,但是僅僅存儲key,並不存儲key對應的value,由於key是不能重復的,且是無序的,所以set是元素不重復的,無序的集合,要創建一個set,需提供一個list作為輸入集合
s = set([2,,3,1]) or s = {2,3,1}: {1,2,3}
add(key):添加元素
remove(key):刪除元素
因為set可以看作是數學上的沒有重復元素,無序的集合,所以set可以做交(&),並(|)等操作
不可變對象:
str是不可變對象,list是可變對象
如,
a = 'abc'
b =a.replace('a','A')
則,變量a還是指向字符串'abc',變量b則是指向字符串'Abc'
對於不可變對象,調用對象自身的任何方法,不會改變對象本身;相反,這些方法會創建新的對象並返回,這樣就保證了不可變對象本身是永遠不變的
函數:
Python內置了很多有用的函數,可供調用使用,還可以導入第三方包,調用需要的函數。函數名實際上是一個函數變量,是這個函數對象的引用,所以完全可以給這個函數起個”別名“,也就是定義一個新的變量名來指向這個函數對象(類似於變量之間那樣),可以通過help(函數名)這個命令來查看該函數的使用。
定義函數:
在Python中,定義一個函數要使用def語句,然后是函數名、圓括號、括號中的參數和冒號:然后在縮進塊里編寫函數體,函數的返回值用return語句返回。函數體內部的語句在執行時,一旦執行到return時,函數就執行完畢,並將結果返回;如果沒有return,函數執行完畢后也會返回結果,只不過結果是None。return None可以簡寫為return。
空函數:也就是什么事情都不干的函數,作用是充當一個占位符
def non():
pass
函數返回多個值:
實際上返回值是一個tuple,但是在語法上,返回一個tuple可以省略括號,而多個變量可以同時接收一個tuple,按位置賦給對應的值。所以,python的函數返回多值實際上就是返回一個tuple。
函數參數:
定義函數時,我們把參數的名字和位置確定下來,函數的接口就完成了。對於調用者來說,無需知道函數內部的復雜實現邏輯,他只要知道,傳入哪些正確的參數,返回一個什么樣的值就行啦。
python函數的定義非常簡單,但靈活度很大,對於函數參數,不僅可以有必選參數,還可以有可選參數,可變參數和關鍵字參數。
必選參數(位置參數):
def power(x,n): s = 1 while n > 0: n = n-1 s = s * x return s
power(x,n): x ,n都是位置參數,調用函數時,傳入的值按照位置順序依次賦給參數x和n
默認參數:
def power(x,n=2): s = 1 while n > 0 n = n-1 s = s * n return s
這樣,當傳入一個值的時侯power(5):就是計算5的平方;
設置默認參數的時候需要注意:
位置參數在前,默認參數在后,否之解釋器會報錯
當函數有多個參數時,把變化大的參數放前面,變化小的參數放后面。變化小的參數就可以作為默認參數。
定義默認參數要牢記一點,默認參數必須指向不變對象(字符串,整數,浮點數,None等)
可變參數:
要定義一個可變參數的函數,我們把輸入作為一個list或者tuple傳進來,這樣,函數可以這樣定義
def calc(numbers): sum = 0 for n in numbers: sum = sum + n*n return sum
但是,在調用時需要先將輸入組裝成list或者tuple:calc([1,2,3])或者calc((1,2,3))
如果利用可變的參數,可以把調用簡化為:calc(1,2,3)
所以,可變參數定義如下:
def calc(*numbers): sum = 0 for n in numbers: sum = sum + n*n return sum
定義一個可變參數函數,和定義一個接收list或者tuple的參數函數相比,僅僅在參數numbers前多了一個*號。在參數內部,函數接收的時一個tuple,因此函數代碼不用改變。
如果說,已經有一個list或者tuple,調用可變參數怎么辦呢?
nums = [1,2,3];
只需要把nums變為*nums
關鍵字參數:
可變參數允許你傳入0個或任意個參數,這些可變參數在函數調用時自動組裝為一個tuple。而關鍵字參數允許你傳入0個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝為一個dict。
如:
def person(name,age,**kw): print(name,age,'other:',kw) person('doublelin','23',city='Heifei'): doublelin 23 other:{'city':'Beijing'}
extra = {'city':'Heifei','job':'Student'}
和可變參數類似,也可以先組裝出一個 extra字典,然后,把該dict轉換為關鍵字參數傳入進去,我們使用**變量名,將這個dict的所有key-value用關鍵字參數傳入到函數的**kw參數,kw將獲得一個dict,注意kw獲得的dict是extra的一份拷貝,對kw的改動不會影響到函數外的extra.
命名關鍵字參數:
對於關鍵字參數,函數的調用者可以傳入任意不受限制的關鍵字參數。如果要限制關鍵字參數的名字,就可以用命名關鍵字參數,例如:僅僅接收city和job作為關鍵字參數。
def person(name,age,*,city,job,**kw): print(name,age,city,job,'other:',kw) person('doublelin','23',city='Hefei',job='Student',learn_language='Python') doublelin 23 Hefei Student other: {'learn_language': 'Python'}
和關鍵字參數**kw不同,命名關鍵字參數需要一個特殊分隔符*,*后面的參數視為命名關鍵字參數。需要將命名關鍵字參數排在關鍵字參數之前。
如果函數定義中已經有了一個可變參數,后面跟着的命名關鍵字參數就不再需要一個特殊分隔符*了。當然,命名關鍵字參數也可以在函數定義時,添加默認值,調用時,可以不傳入具有默認值的命名關鍵字參數。
參數組合:
在Python中定義函數,可以用必選參數、默認參數、可變參數、關鍵字參數和命名關鍵字參數,這5種參數都可以組合使用。但是,參數定義的順序必須是:必選參數、默認參數、可變參數、命名關鍵字參數和關鍵字參數。
如:
def f1(a,b,c=0,*args,**kw): print(a,b,c,'args=',args,'kw=',kw)
通過一個tuple和dict,可以這樣調用上述函數:
args = (1,2,3,4)
kw={'d':99,'x':'#'}
f1(*args,**kw)
輸出: 1 2 3 args= (4,) kw= {'d': 99, 'x': '#'}
所以,對於任意函數,都可以通過類似func(*args,**kw)的形式調用它,無論它的參數是如何定義的。
遞歸函數:
當函數調用自身函數時,該函數就是遞歸函數;遞歸函數邏輯清晰,簡單實現,但因為函數調用是通過棧這個數據結構實現的,每當進行一個函數調用,棧就會增加一層棧幀。由於棧的大小有限,所以進行多次遞歸函數,會導致棧溢出。理論上,所有的遞歸函數都可以寫成循環的方式。
漢諾塔--遞歸函數實現:
def move(n,a,b,c): if n==1: print(a,'-->',c) else: move(n-1,a,c,b) print(a,'-->',c) move(n-1,b,a,c)
move(3,'A','B','C')
輸出:
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C