python3基礎11
day11
函數語言程式設計
是指用一系列函式解決問題
示例:
求1 + 2 + 3 + ....+ 100的和
方法一
s = 0
for x in range(1,101):
s += x
print(s)
方法二
print(sum(range(1,101)))
函式的可重入性:
當一個函式輸入一定,則輸出必然一定的函式稱為可重入性函式
說明:
可重入函式內一定不會訪問區域性變數以外的變數
示例:
#可重入函式:(推薦使用)
def myadd(x,y):
return x + y
print(myadd(100, 200)) #300
#不可重入函式:
y = 200
def myadd():
return x + y
print(myadd(100)) #300
y = 300
print(myadd(100)) #400
高階函式High Order Function
什麼是高階函式:
滿足下列條件中的一個的函式即為高階函式
1.函式接收一個或多個函式作為引數傳入
2.函式返回一個函式
python內建的高階函式:
map, filter, sorted
map函式:
map(func, *iterable) (*iterable為星號元組形參,可儲存多個物件)
返回一個可迭代物件,此可迭代物件用函式func對可迭代物件iterable中的每一個元素作為引數計算後得到新的資料
示例見:
mymap.py
def power2(x):
return x ** 2
for x in map(power2,range(1,10)):
print(x) #1 4 9 16 ... 81
練習一:
1.求:1**2 + 2**2 + 3**2 + ... +9**2的和
#程式碼
#方法一
def sums(n):
return n**2
s = 0
for n in map(sums,range(1,10)):
s += n
print(s)
#方法二
s = 0
for x in map(lambda x: x ** 2,range(1,10)):
s += x
prnt(s)
#方法三
print(sum(map(lambda x: x ** 2,range(1,10))))
2.求:1**3 + 2**3 + 3**3 + ... +9**3的和
print(sum(map(lambda x: x ** 3,range(1,10))))
示例2見:
mymap2.py
def mypow(x, y):
return x ** y
for i in map(mypow,[1,2,3,4],(4,3,2,1)):
print(i)
#程式碼
練習二:
求1**9 + 2 ** 8 + 3**7 + ... + 9**1的和
# 方法一
def mypow(x, y):
return x ** y
s = 0
for x in map(mypow,range(1,10),range(9,0,-1)):
s += x
print(s)
# 方法二
s = 0
for n in map(lambda x, y:x ** y,range(1,10),range(9,0,-1)):
s += n
print(s)
#方法三
print(sum(map(pow,range(1,10),range(9,0,-1))))
filter函式:
filter(function,iterable)
作用:
篩選可迭代物件iterable中的資料,返回一個可迭代物件,此可迭代物件只返回iterable中符合條件的資料
function將對iterable中提供的每一個數據進行求布林值,如果為True則保留,返回False則丟棄此資料
示例見:
myfilter.py
def isadd(x):
return x % 2 == 1
for x in filter(isadd,range(10)):
print(x)
L = list(filter(isadd,range(10)))
print("L=",L)
練習三:
1.將1~20的偶數用filter生成可迭代物件後,將可迭代物件生成的資料存於列表中
最終結果:
L = [2,4,6,8,10.....18,20]
#程式碼
#方法一
def ou(n):
return n % 2 == 0
L = list(filter(ou,range(2,21)))
print(L)
#方法二
def ou(n):
if n % 2 == 0:
return True
return False
L = list(filter(ou,range(2,21)))
print(L)
#方法三
L = list(filter(lambda n: n%2==0,range(2,21)))
print(L)
2.用filter函式將1~100之間所有的素數放入到列表L中
print(L) #[2,3,5,7....]
def sushu(n):
if n < 2:
return False
for b in range(2,n):
if n % b == 0:
return False
return True
L = list(filter(sushu,range(100)))
print(L)
sorted函式
作用:
將原可迭代物件的資料進行排序,生成排序後的列表
函式參照格式:
sorted(interable,key=None,reverse=False)
說明;
interable 可迭代物件
key
函式是用來提供一個值,這個值作為排序的依據,如果不給出key函式,則用原資料的值進行排序和比較
reverse標誌用來設定是否降序排列
示例:
L = [5, -2, -4, 0, 3, 1]
L2 = sorted(L) #[-4, -2, 0, 1, 3, 5]
L3 = sorted(L,reverse=True) #[5, 3, 1, 0, -2, -4]
L4 = sorted(L,key=abs,reverse=False)
#[0, 1, -2, 3, -4, 5]按絕對值排序
L5 = sorted(L,key=abs,reverse=True)
#[5, -4, 3, -2, 1, 0]
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
L6 = sorted(names)
#['Jerry', 'Spike', 'Tom', 'Tyke']
L7 = sorted(names, key=len)
#['Tom', 'Tyke', 'Jerry', 'Spike']
練習四:
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
排序依據是字串的反序
'moT' 'yrreJ' 'ekipS' 'ekyT'
結果:
['Spike','Tyke','Tom','Spike']
#方法一:
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
S = []
for i in range(len(names)):
S.append(names[i][::-1])
L = sorted(S)
N = []
for x in range(len(L)):
N.append(L[x][::-1])
print(N)
#方法二:
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
def k(s):
return s[::-1]
L = sorted(names,key=k)
print(L)
遞迴函式 recurison
遞迴是指 函式直接或間接呼叫自身
遞迴示例:
#函式直接呼叫自身
def f():
f() #直接呼叫自身
f()
print("遞迴完成")
#函式間接呼叫自身
def fa():
fb()
def fb():
fa()
fa()
print("遞迴完成")
遞迴說明:
遞迴一定要控制遞迴的層數,當符合某一條件時要終止遞迴呼叫,幾乎所有的遞迴都能用while迴圈來代替
遞迴的優缺點:
優點:
可以把問題簡單化,讓思路理會清晰,程式碼更簡潔
缺點:
遞迴因系統環境影響大,當遞迴深度太大時,可能會得不到預知的結果
遞迴呼叫分為兩個階段:L
遞推階段:
從原問題出發,按遞迴公式遞推,從未知到已知,最終達到遞迴終止條件
迴歸階段:
按遞迴終止條件得出結果,逆向逐步帶入遞迴公式,迴歸到原問題的求解
示例:
限制遞迴層數的示例見:
recurison2.py
def fx(n):
print("遞迴進入第",n,'層')
if n == 3:
return
fx(n+1)
print("遞迴退出第",n,'層')
fx(1) #呼叫
print("程式結束")
#結果:
# 遞迴進入第 1 層
# 遞迴進入第 2 層
# 遞迴進入第 3 層
# 遞迴退出第 2 層
# 遞迴退出第 1 層
# 程式結束
遞迴求階乘示例見:
recurison_factorial.py
def myfac(n):
#5! = 5 * 4!
#5! = 5 * 4! * 3!
#5! = 5 * 4! * 3! * 2!
#5! = 5 * 4! * 3! * 2! * 1!
#5! = 5 * 4! * 3! * 2!
#5! = 5 * 4! * 3!
#5! = 5 * 4!
if n == 1:
return 1
#如果不是1,則遞推到下一級求解
return n * myfac(n - 1)
print(myfac(5))
print(myfac(4))
練習五:
用遞迴實現求和:
def mysum(n):
#返回 1+2+3+4+5+...+n的和
print(mysum(100))
#程式碼
def mysum(n):
if n == 1:
return 1
return n + mysum(n - 1)
print(mysum(100))
閉包 closure
什麼時閉包
閉包是指引用了此函式外部變數的函式
如果一個內嵌函式訪問了外部巢狀函式的變數,則這個內嵌函式就是閉包
閉包必須滿足的三個條件:
1.必須有一個內嵌函式
2.內嵌函式必須引用外部函式中的變數
3.外部函式返回值必須是內嵌函式
示例見:
closure.py
def make_power(y):
def fn(x):
return x ** y
return fn
pow2 = make_power(2)
print("5的平方是:",pow2(5))
def pow3(x):
return x**3
pow3 = make_power(3)
print('6的三次方是:',pow3(6))
print('5的三次方是:',pow3(5))
pow10 = make_power(10)
print('2的十次方',pow10(2))
練習六:
已知有五位朋友在一起
第五個人說他比第四個人大2歲
第四個人說他比第三個人大2歲
第三個人說他比第二個人大2歲
第二個人說他比第一個人大2歲
第一個人說他十歲
編寫程式:
1.算出第5個人幾歲?
2.算出第3個人幾歲?
def myage(x):
return (x-1)*2+10
print(myage(3))
print(myage(5))
def myage(x):
if x == 1:
return 10
return myage(x - 1) + 2
print(myage(3))
print(myage(5))
課後練習:
1.寫程式算出1~20的階乘的和
1!+2!+3!+4!+.....+20!
#方法一:
def myfac(n):
if n == 1:
return 1
return n * myfac(n - 1)
# L = []
# for i in range(1,21):
# L.append(myfac(i))
# print(sum(L))
print(sum(map(myfac,range(1,21))))
#方法二:
def myfac(n):
s = 1
for i in range(1,n+1):
s = s * i
return s
def sum_factorial(n):
s = 0
for i in range(1, n):
s += myfac(i)
return s
print(sum_factorial(20))
2.已知有列表:
L = [[3,5,8], 10, [[13,14],15,18],20]
(1)寫一個函式print_list(lst)打印出所有的數字
print_list(L) #3 5 8 10 13.....
(2)寫一個函式sum_list(lst)返回字列表中所有數字的和
print(sum_list(L)) #106
注:
type(x)函式可以返回一個物件的型別
如:
>>>type(20) is int #True
>>>type([3, 5, 8]) is list #True
>>>type(20) is list #False
L = [[3,5,8], 10, [[13,14],15,18],20]
def print_list(lst):
for i in lst:
if type(i) is int:
print(i)
if type(i) is list:
print_list(i)
print_list(L)
def sum_list(lst):
s = 0
for x in lst:
if type(x) is int:
s += x
elif type(x) is list:
s += sum_list(x) #求x繫結列表的和
return s
print("和是:", sum_list(L))
(3)改寫之前的學生資訊的程式,要求新增四個功能:
| 5)按學生成績高-低顯示學生資訊 |
| 6)按學生成績低-高顯示學生資訊 |
| 7)按學生年齡高-低顯示學生資訊 |
| 8)按學生年齡低-高顯示學生資訊 |
def input_student(L):
L = []
while True:
a = input("請輸入姓名:")
if a == '':
break
b = int(input("請輸入年齡: "))
c = int(input("請輸入成績: "))
d = {}
d["name"] = a
d['age'] = b
d['score'] = c
L.append(d)
return L
def get_chinese_char_count(s):
c = 0
for i in s:
if ord(i) > 127:
count += 1
return c
def output_student(L):
m = 0
for i in L:
j = i["name"]
m = max(len(j),m)
count = get_chinese_char_count(j)
print('+'+'-'*(m-count)+'+'+'-'*m+'+'+'-'*(m+1)+'+')
print('|'+'name'.center(m)+'|'+'age'.center(m)+'|'+'score'.center(m+1)+'|')
print('+'+'-'*(m-count)+'+'+'-'*m+'+'+'-'*(m+1)+'+')
for i in L:
j = i["name"]
p = str(i["age"])
q = str(i["score"])
print('|'+j.center(m)+'|'+p.center(m)+'|'+q.center((m+1))+'|')
print('+'+'-'*(m-count)+'+'+'-'*m+'+'+'-'*(m+1)+'+')
def delete_student(L):
n = input("請輸入您要刪除資訊學生的名字:")
print("正在刪除學生資訊")
for a in L:
if a["name"] == n:
L.remove(a)
print("學生資訊已經刪除")
break
else:
print("您輸入的姓名不存在")
return L
def alter_student(L):
a = input("請輸入您要修改資訊的學生名字:")
b = input("請輸入您要修改資訊的學生年齡:")
c = input("請輸入您要修改資訊的學生成績:")
for m in L:
if m["name"] != a:
print("學生不存在")
if m["name"] == a:
m["age"] = b
m["score"] = c
print("學生資訊已經修改")
return L
def score_high_student(L):
def get_score(d): #d是字典
return d['score']
L2 = sorted(L, key=get_score, reverse=True)
output_student(L2)
def score_low_student(L):
def get_score(d): #d是字典
return d['score']
L2 = sorted(L, key=get_score, reverse=False)
output_student(L2)
def age_high_student(L):
L2 = sorted(L, key=lambda d:d['age'], reverse=True)
output_student(L2)
def age_low_student(L):
L2 = sorted(L, key=lambda d:d['age'])
output_student(L2)
def operate():
print("+------------------------------+")
print("|1)新增學生資訊 |")
print("|2)顯示學生資訊 |")
print("|3)刪除學生資訊 |")
print("|4)修改學生資訊 |")
print("|5)按學生成績高-低顯示學生資訊 |")
print("|6)按學生成績低-高顯示學生資訊 |")
print("|7)按學生年齡高-低顯示學生資訊 |")
print("|8)按學生年齡低-高顯示學生資訊 |")
print("|q)退出 |")
print("+------------------------------+")
def main():
L = []
while True:
operate()
x = input("請輸入您的選擇:")
if x == 'q':
break
elif x == '1':
L += input_student(L)
elif x == '2':
output_student(L)
elif x == '3':
delete_student(L)
elif x == '4':
alter_student(L)
elif x == '5':
score_high_student(L)
elif x == '6':
score_low_student(L)
elif x == '7':
age_high_student(L)
elif x == '8':
age_low_student(L)
main()