==漢諾塔==
時間戳:2023年3月6日23:38:55
常用函式呼叫 abs() max() float() str() bool() hex()isinstance(x,(int,str))
定義乙個函式 使用關鍵字 def 例如:
def
my_abs
(x):
if x:
return x
else
:return
-x
如果沒有return語句,函式返回none
定義乙個空函式
def
nop():
pass
pass可以作為佔位符,充當乙個能代替乙個將要完成的**塊
在命令列匯入某個檔案的某個函式 from 檔名 import 函式名
函式可以返回多個值,在return 語句中用 , 隔開return返回的真是值其實是乙個單一的tuple,tuple在return語句中可以省略括號,並且用多個引數來接受這個tuple
python有必選引數、預設引數、可變引數和關鍵字引數
def
f1(x)
:#x為必選引數
print
(x)def
f2(x,y =1)
:#x為必選引數,y為預設引數,必選在前,預設在後
print
(x,y)
deff3
(x =
1,y =2)
:print
(x,y)
#多個預設引數的呼叫
f3()
# x = 1,y = 2
f3(3
)# x = 3,y = 2
f3(3,4
)# x = 3,y = 4
f3(y=2)
# x = 1,y = 2
定義預設引數時,引數一定要是不可變引數
如果定義成可變引數會有乙個大坑。如:
def
f(x =
):'end'
)print
(x)f(
)# 列印['end']f()
# 列印['end','end']f()
# 列印['end','end','end']
發生了什麼?在定義函式 f 時,x引數被預設繫結的值 是 指向物件 的引用在以後使用預設值呼叫f時,永遠都使用最初定義的那個引用
在python中不變物件好像很重要的樣子,還有多工環境(是多執行緒嗎)對這些物件處理
即函式的引數個數可變
deff(
*x):
for m in x:
print
(m)f(1)
# print(1)f(1
,2,3
)# print(1) print(2) print(3)f(*
[1,2
,3,4
,7])
#呼叫可變引數的函式,可以用前面標*的 list 或 tuple 傳入
可變引數的呼叫,實質上會把傳入的引數在底層包裝成乙個tuple做處理
即可為函式傳入帶有引數名的引數,並且引數數量可變,多應用於介面的擴充套件,讓呼叫者可以提供更多資訊
方法,用雙*標識引數dict,傳入dict的備份
def
f(x,
**kv)
:print
(kw)
f(10
,hello =
'jim'
)#傳入了變數hello
extrainfo =
f(**extrainfo)
#傳入了變數 money,傳入了extrainfo的乙個備份,在函式中的操作並不會改變變數extrainfo
普通關鍵字引數,變數名不受限制。如果命名了關鍵字引數則可以限制關鍵字引數的名稱
方法用乙個 *變數 或者 可變引數 *x 變數隔開,這樣命名的關鍵字引數就變成了必選的引數,它們的傳入順序是可變的,當然也可以給關鍵字引數預設乙個值,這樣傳入時就可預設該關鍵字。
def
f(x,y,
*,city,room)
:pass f(
1,2,city =
3,room =4)
f(1,2
,room =
4,city =3)
defff
(x,y,
*,city,room =1)
:pass
ff(1,
2,city =
3)
以上幾種引數可以組合起來使用,但是要遵守定義順序,從前到後,分別是必選引數、預設引數、可變引數、命名關鍵字引數和關鍵字引數。
def
f(x,y =1,
*args,city,room,desk =1,
**kv)
:print
(x,y,args,city,room,desk,kv)
pass
f(10,11
,12,13
,city =
20,room =30)
#print: 10 11 (12, 13) 20 30 1 {}
函式內部呼叫函式本身
最經典的是階乘的計算
n! = 1 * 2 * 3 * 4*…* n
用fact(n)計算結果:
def
fact
(n):
if n ==1:
return
1else
:return n * fact(n-
1)
理解 n * fact(n-1)
fact(n-1) 可以視為 (n-1)*fact(n-2)
fact(n-2) 可以視為 (n-2)*fact(n-3) …
歸納, n * (n-1) * (n - 2) * (n - 3)… 2 * f(1)
使用遞迴函式要注意防止棧溢位,計算機中函式呼叫是通過棧(stack)結構實現。棧的大小是一定的,類似的比如另一種解釋型語言lua的函式呼叫棧是200,超過200個函式的呼叫就會報錯。即在lua 呼叫fact(201) 就會導致程式報錯。
為防止函式呼叫棧溢位,可以使用尾遞迴進行優化,即 return 後邊的表示式只能是函式的呼叫,不能有其他對函式f的計算。這樣每次呼叫時都退出上一次的呼叫,只會占用棧的1個位置。但很遺憾的是大多數程式語言包括python都沒有對尾呼叫進行優化
def
f(x)
:if x:
x--return f(x)
else
:return
1
我測試了一下,如果不使用尾呼叫,fact(999),就會報錯recursionerror: maximum recursion depth exceeded in comparison;使用了尾呼叫依舊會報同樣的錯誤
尾呼叫的效果是和迴圈一樣的。python居然沒有for的步長迴圈。
a b c三個柱子,a柱子套著n個從下到上且從大到小的圓環,b,c 是空柱子,借助b柱,將a柱所有圓環按順序套在c柱上。移動過程中,每次只能移動乙個圓環,並且小圓環上不能套大圓環。
使用遞迴方法編寫函式 move(n,a,b,c)
#aa = ,,]} #src
#aa = ]} #src
aa =,,
]}#src
bb =
#assist
cc =
#dest
defmove
(n,src,assist,dest)
:if n ==1:
moveonce(src,dest)
else
: move(n-
1,src,dest,assist)
move(
1,src,assist,dest)
move(n-
1,assist,src,dest)
defmoveonce
(src,dest)
: circle = src[
'list'
].pop(
) dest[
'list'
]print
(src[
'name'],
'-->'
,dest[
'name'])
print
(aa,bb,cc)
move(
len(aa[
'list'])
,aa,bb,cc)
>>
>輸出:
a --
> c,]
}]}a -
-> b]}
]}]}
c --
> b]}
,]}a -
-> c,]
}]}b -
-> a]}
]}]}
b --
> c]}
,]}a -
-> c,,
]}
python淺學筆記20 非同步IO
cpu速度遠遠快於 網路 磁碟 io 在乙個執行緒裡,io會阻塞其它 的執行。為了不阻塞,就要用多執行緒或多程序,雖然併發可以解決這個問題,但是系統不能無上限的增加執行緒,系統切換執行緒的開銷也很大 另一種解決問題的方法非同步io,cpu負責 的執行,io操作由io裝置執行,負責開啟乙個io操作,並...
linux C淺學大綱 2
define start 2018.1.5號是意義非凡的一天。寫之前說明下為什麼寫,怎樣寫,怎樣學。本人,小白。在某培訓機構培訓了幾個月,寫出來的東西,膚淺,有誤,請賜教。此文章,寫給那些,想學,卻摸不到大綱的同仁。二.基礎知識擴充套件 學習linux c之前,應該先掌握,標準c語言基本知識。1 鍊...
python淺學筆記9 IO程式設計
stringio和bytesio 操作檔案和目錄 序列化 pickling name input output face 磁碟,網路 model stream 流 from to 記憶體 time stop?同步 非同步 由於非同步io比較複雜,本章都是同步io,非同步io在後邊網路伺服器提及。開啟...