標籤:絕對值 三元運算 contain 括弧 sort min 函數調用 維護 nbsp
本節內容
1. 函數基本文法及特性
2. 參數與局部變數
3. 傳回值
嵌套函數
4.遞迴
5.匿名函數
6.函數式編程介紹
7.高階函數
8.內建函數
函數是什麼?
函數一詞來源於數學,但編程中的「函數」概念,與數學中的函數是有很大不同的,具體區別,我們後面會講,編程中的函數在英文中也有很多不同的叫法。在BASIC中叫做subroutine(子過程或子程式),在Pascal中叫做procedure(過程)和function,在C中只有function,在Java裡面叫做method。
定義: 函數是指將一組語句的集合通過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名即可
特性:
- 減少重複代碼
- 使程式變的可擴充
- 使程式變得易維護
def 函數名(): 括弧是用來傳參的,靈活應用
函數名() #調用
形參:變數只有在被調用時才分配記憶體單元,在調用結束時,即刻釋放所分配的記憶體單元。因此,形參只在函數內部有效。函數調用結束返回主調用函數後則不能再使用該形參變數
實參:可以是常量、變數、運算式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使參數獲得確定值
def sayhi(name,age,nationality=‘CN‘): -----name、age是形參 ,有的預設參數都放在非預設參數(位置參數)的右邊 print(‘i am %s,‘ %name,age,nationality) -----如果不調用,就安預設列印,sayhi(‘haha‘,22) ------haha、22是實參sayhi(‘haha‘,22,US) ------如果傳參的話就列印傳入的內容sayhi(name = ‘11‘,22) ------指定參數傳參,也的放在位置參數後面 關鍵參數,如果給其中一個寫定,並且不按順序寫,其他的都的寫定。
關鍵參數
正常情況下,給函數傳參數要按順序,不想按順序就可以用關鍵參數,只需指定參數名即可,但記住一個要求就是,關鍵參數必須放在位置參數之後。
?
| 1 |
stu_register(age=22,name=‘alex‘,course="python",) |
非固定參數
若你的函數在定義時不確定使用者想傳入多少個參數,就可以使用非固定參數。
def sayhi(name,age,nationality=‘CN‘,*args): *args以元組的形式存在,如果寫單個元素就是元組。
def sayhi(name,age,nationality=‘CN‘,**kwargs) **kwargs以字典的形式存在,如果寫name = ‘lwq‘,就寫入字典中。
全域與局部變數
在子程式中定義的變數稱為局部變數,在程式的一開始定義的變數稱為全域變數。全域變數範圍是整個程式,局部變數範圍是定義該變數的子程式。當全域變數與局部變數同名時:在定義局部變數的子程式內,局部變數起作用;在其它地方全域變數起作用。
login_status = False #全域變數 雖然與局部變數名字相同,但是在記憶體中的地址不一樣def auth(username,password): #get date from db _username = ‘alex‘ _password = ‘alex3714‘ if username == _username and password == _password: print(‘ok‘) #global login_status #改全域變數,要用global,並且將原來的全域變數寫上 login_status = True #局部變數,只在函數中生效 print(‘--->‘,login_status)def home(): if login_status ==True: print(‘welcome‘) else: auth()def pay(): if login_status == True: print(‘welcome‘) else: auth()username = input(‘username:‘).strip()password = input(‘password:‘).strip()auth()
傳回值:
1.一旦你的函數經過調用並開始執行,那你的函數外部的程式就沒有辦法再控制函數的執行的過程了,此時外部程式只能等待函數的執行結果,因為外部程式要根據外部函數的執行結果來決定下一步如何走,
執行結果就是以return的形式返回給外部程式。
2.return代表著一個函數的結束。
3.return可以返回python中的任何資料類型,一次能返回多個值,以元組的形式返回。
4.對於使用者角度,函數可以返回任意數量的值,但對於py本身來講,函數只能返回一個。
def auth(): username = input(‘username:‘).strip() password = input(‘password:‘).strip() #get date from db _username = ‘alex‘ _password = ‘alex3714‘ if username == _username and password == _password: print(‘ok‘) return True else: return Falsedef home(): if login_status ==True: print(‘welcome‘) else: auth()def pay(): if login_status == True: print(‘welcome‘) else: auth()login_status = auth()home()pay()
嵌套函數
name = ‘alex‘def changeName(): name = ‘jack‘ print(name) def changeName2(): name = ‘rain‘ print(‘name2‘, name) changeName2()changeName()
遞迴函式
特性:
1.必須有一個明確的結束條件
2.每進入更深一層遞迴時,問題規模相比上次遞迴都應有所減少
3.遞迴效率不高,遞迴層次過多會導致棧溢出(在電腦中,函數調用是通過stack這種資料結構實現的)
每當進入一個函數,棧就會加一層棧幀,每當函數減少一層,棧幀就減少一層。
遞迴函式的典型案例:二分尋找
#data = [3,5,10,1,12,14,17,11,19,20,19]#date = [1,3,5,10,11,12,14,17,19,19,20]date = range(0,10000,3) #range 出來就是列表def binary_search(datasets,find_num): if len(datasets) > 0: middle_pos = int(len(datasets)/2) if date[middle_pos] == find_num: print(‘Find num:‘,datasets[middle_pos]) elif date[middle_pos] > find_num: print(‘go to left side‘,datasets[0:middle_pos],datasets[middle_pos]) binary_search(datasets[0:middle_pos],find_num) else: print(‘go to righ side‘,datasets[middle_pos+1:],datasets[middle_pos]) binary_search(datasets[middle_pos+1:],find_num) else: print(‘cannot not find num‘)binary_search(date,15)
匿名函數:
匿名函數就是不需要顯式的指定函數
正常定義函數:
def calc(n): return n*n
print(cacl)
def calc(n,j):
return n*j
print(cacl)
匿名函數:
calc2 = lambda x:x*xprint(cacl2)
calc2 = lambda x,y:x*x
calc(8)
與map函數搭配使用
data = map(lambda n:n*2 if n>5 else n,range(10))
data = map(lambda n:n*2 if n>5 else calc(n),range(10))
def cal(n):
return -n
data = map(lambda n:n**n if n>5 else cal(n),range(10))
for i in data:
print(i)
三元運算
a =4
b= 5
c = if a >10 else b
上面的匿名函數與map搭配使用中就用到了三元運算。
函數式編程介紹
函數是Python內建支援的一種封裝,我們通過把大段代碼拆成函數,通過一層一層的函數調用,就可以把複雜任務分解成簡單的任務,這種分解可以稱之為面向過程的程式設計。函數就是面向過程的程式設計的基本單元。
函數式編程中的函數這個術語不是指電腦中的函數(實際上是Subroutine),而是指數學中的函數,即自變數的映射。也就是說一個函數的值僅決定於函數參數的值,不依賴其他狀態。比如sqrt(x)Function Computex的平方根,只要x不變,不論什麼時候調用,調用幾次,值都是不變的。
Python對函數式編程提供部分支援。由於Python允許使用變數,因此,Python不是純函數式程式設計語言。
一、定義
簡單說,"函數式編程"是一種"編程範式"(programming paradigm),也就是如何編寫程式的方法論。
主要思想是把運算過程盡量寫成一系列嵌套的函數調用。舉例來說,現在有這樣一個數學運算式:
(1 + 2) * 3 - 4
傳統的過程式編程,可能這樣寫:
var a = 1 + 2;
var b = a * 3;
var c = b - 4;
函數式編程要求使用函數,我們可以把運算流程定義為不同的函數,然後寫成下面這樣:
var result = subtract(multiply(add(1,2), 3), 4);
這段代碼再演化以下,可以變成這樣
add(1,2).multiply(3).subtract(4)
這基本就是自然語言的表達了。再看下面的代碼,大家應該一眼就能明白它的意思吧:
merge([1,2],[3,4]).sort().search("2")
因此,函數式編程的代碼更容易理解。
高階函數
變數可以指向函數,函數的參數能接收變數,那麼一個函數就可以接收另一個函數作為參數,這種函數就稱之為高階函數。
abs求絕對值def add(x,y,f): return f(x) + f(y)def calc(n): return n+1res = add(3,-6,cacl)print(res)
編程範式:
1.面向過程
2.物件導向
3.函數式編程
內建函數
python內建
a = [1,2,3]
all(a)
#判斷是否為真
any() #列表任意一個為真就返回真
ascii() #顯示成ascii表的東西
bin() #將數字轉成二進位
print(bin(10))
bool #判斷是否為true
bytes #0-255之間的數字,ascii表
bytearray #改bytes值
callable() #判斷對象是否可以被調用
chr() #把數字轉換成二進位
print(chr(97)) #列印ascii表的對應關係
print(ord(‘b‘)) #將字元對應成ascii表中的數字
f = open(‘遞迴.py‘,encoding=‘utf-8‘)
code = compile(f.readline(),‘‘,‘exec‘)
print(code)
exec(code) #執行這段代碼,這段代碼是字串
eval() #數字運算
complex #複數
complex(4,5)
print(dir(f)) #dir返迴文件的方法
divmod() #地板除,放回商和餘數
divmod(10,2)
filter #過濾
for i in filter(lambda x:x>5,range(10)):
print(i)
format() #字串格式化
frozenset({1,4,5,5,6}) #把集合變成唯讀
print(a)
#就沒有add方法
globals()
print(globals()) #把當前程式所在記憶體中所有的資料都以字典的形式列印出來
locals() #只列印局部
hex() #十六進位
print(hex(8))
max() #返回列表匯總最大值
print(max())
min() #返回最小值
oct() #八進位0o8
print(pow(4,9)) #4**9
#分隔字元
msg = "又回到最初的起點"
f = open("tofile","w")
print(msg,"記憶中你青澀的臉",sep="|",end="",file=f)
data = [1,2,3,5,8]
data = reversed(data) #反轉(字串、列表)
for i in data:
print(i)
round() #五舍六入
print(round(10.25,1))
data = [10,2,4]
print(set(data)) #將列表變成集合
#切片
a = range(20)
pattern = slice(3,8,1)
for i in a[pattern]:
print(i)
a= ‘alex‘
a= sorted(a) #按ascii碼排序
print(a) 以列表的形式列印,字元竄、集合、列表(並且其中只能由一種資料類型)
data = [10,2,3,45,56,3]
print(sum(data)) #相加 列表、集合、元組都可相加。
print(vars()) #列印當前程式在記憶體中的所有資料
zip # 類似拉鏈效應,如果對應不上,就按少的來
a = [1,3,5,7]
b = [2,4,6,8]
for i in zip(a,b):
print(i)
python之路-Day4