python之函數(shù)
先通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)了解一下函數(shù)的概念:
定義一個(gè)累和函數(shù)caculatenum
def caculateNum(Num):
res = 0
for i in range(1,Num+1):
res += i
return res
res = caculateNum(100)
print(res)#5050
返回值return也可以直接用來(lái)定義函數(shù),比如
def caculateNum(Num):
return sum([i for i in range(1,Num+1)])
res = caculateNum(100)
print(res)#5050
一演训,必須參數(shù)和關(guān)鍵字參數(shù)
1.必須參數(shù)
必須參數(shù)必須以正確的順序傳入限佩,調(diào)用的時(shí)候必須和聲明的時(shí)候保持一致
如:
def f(name, age):
print('I am %s , I am %d years old'%(name,age))
f(18,'wxn')#報(bào)錯(cuò)
之所以會(huì)報(bào)錯(cuò)是因?yàn)?8前鹅,wxn沒(méi)有與定義參數(shù)時(shí)的必須參數(shù)類型相對(duì)應(yīng)
這里就涉及到格式化輸出的問(wèn)題了毒租,%s代表字符串赘被,%d代表十進(jìn)制整數(shù)
2.關(guān)鍵字參數(shù)
關(guān)鍵字參數(shù),使用關(guān)鍵字參數(shù)可以允許函數(shù)調(diào)用時(shí)和聲明時(shí)順序不一致
瞧剖,python 解釋器能夠用參數(shù)名字匹配參數(shù)值
如:
def f(name, age):
print('I am %s , I am %d years old'%(name,age))
f(age=18,name='verg')#I am verg , I am 18 years old
這里就用到了age和name這兩個(gè)關(guān)鍵詞
二废境,默認(rèn)參數(shù)
默認(rèn)參數(shù) 缺省參數(shù)沒(méi)有傳入,默認(rèn)值會(huì)生效
def f(name,age,sex = 'male'):
print('I am %s , I am %d years old' % (name, age))
#I am lisi , I am 19 years old
#sex : male
print('sex : %s'%sex)
#I am 張三 , I am 88 years old
#sex : famale
f(name='lisi',age=19)
f('張三',88,'famale')
三筒繁,匿名函數(shù)
lambda 參數(shù):表達(dá)式
冒號(hào)前面是參數(shù),可以有多個(gè)巴元,后面是表達(dá)式毡咏,只能是一個(gè)表達(dá)式
不寫(xiě)return,返回值就是表達(dá)式的結(jié)果
減少代碼量逮刨,代碼看起來(lái)有逼格
res = lambda x , y :x*y
print(res(4,5))#20
store = []
s = "淘寶"if len(store)==0 else store[0]
即如果if后面的條件滿足則返回if前的的內(nèi)容
否則返回store列表的第一個(gè)數(shù)值即store[0]
print(s)#淘寶
說(shuō)明條件滿足
下面通過(guò)舉例說(shuō)明lambda函數(shù)的方便之處
def cal(x,y):
if x>y:
return x*y
else:
return x/y
print(cal(3,4))#0.75
使用lambda函數(shù):
calc = lambda x,y:x*y if x>y else x/y
print(calc(2,3))#0.666666
冒號(hào)前面是參數(shù)呕缭,后面是表達(dá)式,而且不需要返回值return修己,非常方便了
用sorted(列表名恢总,key=lambda 參數(shù):元素)的方法直接給列表排序
stus = [
{'name':'ae','age':1,},
{'name':'ga','age':2,},
{'name':'pa','age':4,},
{'name':'ba','age':9,},
{'name':'va','age':5}
]
#key值是按照哪個(gè)元素為依據(jù)進(jìn)行排序
res = sorted(stus,key=lambda x:x['age'])#取age的值進(jìn)行排序
print(res)
res = sorted(stus,key=lambda x:x['name'])#根據(jù)名字的首字母順序進(jìn)行排序
print(res)
四,兩種傳參方式
按位置傳參與按關(guān)鍵詞傳參
def get_fullname(last_name,first_name):
full_name = last_name + first_name
return full_name
full_name = get_fullname('wang','xinnan')
full_name = get_fullname(first_name= 'xinnan',last_name='wang')
print(full_name)
這里需要注意按關(guān)鍵詞傳參的時(shí)候有默認(rèn)值的要放在最后面
五睬愤,變長(zhǎng)參數(shù)
*的作用:1.將參數(shù)打包成元組
def self_print(*a):#用*將參數(shù)都放置到一個(gè)元組中
print(a)#(1, 2, 3, 4, 5, 6)
print(type(a))#<class 'tuple'>元組片仿,元組參數(shù)不可改變
self_print(1,2,3,4,5,6)
def self_print(name,*a):
print(a)#(2, 3, 4, 5, 6)
print(name)#1
self_print(1,2,3,4,5,6)
這里self_print的第一個(gè)數(shù)值1傳給了參數(shù)name,剩下的2尤辱,3砂豌,4,5光督,6在的打包下都傳給了a
2.如果參數(shù)本身就是一個(gè)元組或者列表阳距,能在輸出的時(shí)候?qū)⑺痖_(kāi)
如:
t = (1,2,3,4,5)
print(*t)#1 2 3 4 5 沒(méi)有括號(hào)
def f(*tt):
print(tt)#(1, 2, 3, 4, 5)
f(*[1,2,3,4,5])
**的作用:1.將參數(shù)都放到字典中,注意這個(gè)參數(shù)必須有關(guān)鍵字
def d_self_print(**kwargs):
print(kwargs)
d_self_print(last_name = "wang",frist_name = "xinnan")#{'last_name': 'wang', 'frist_name': 'xinnan'}
形參順序:位置參數(shù)->元組->字典
def mix(name,*t,**kwargs):#kwargs是關(guān)鍵字參數(shù)的意思
print(name)#wangxinnan
print(t)#('20', 'dongqin')
print(kwargs)#{'gender': '魯班'}
mix('wangxinnan','20','dongqin',gender = '魯班')#帶關(guān)鍵詞的應(yīng)該放在最后
return 返回值
def sum_and_avg(*numbers):
total = sum(numbers)
avg_number = total/len(numbers)
return total,avg_number
sum,avg = sum_and_avg(1,2,3,4,5,6,7,8,9,10)
print("總和是%f"% sum)#總和是55.000000
print("平均值是%f"%avg)#平均值是5.500000
函數(shù)的傳參問(wèn)題
1.數(shù)據(jù)分為引用類型和普通類型
python中的基本數(shù)據(jù)類型都是普通類型,數(shù)结借,布爾型筐摘,字符串型
除了這些以外的類型都是引用類型
普通類型賦值的時(shí)候,傳的是值船老,引用類型賦值的時(shí)候傳的是地址
舉個(gè)例子
l1 = [1,2,3,4,5]
l2 = l1
l2[1] = 5
print(l1)#[1, 5, 3, 4, 5]
這里的l1中的參數(shù)屬于引用類型咖熟,所以l1 l2共用同一個(gè)地址,所以在更改了l2中的第二個(gè)數(shù)據(jù)后l1中的也會(huì)一起更改努隙,所以傳參的本質(zhì)就是賦值操作球恤,如果傳遞的是引用類型數(shù)據(jù),則需要注意是否在函數(shù)中對(duì)其做出了修改
def power(numbers):
numbers = [x**2 for x in numbers]
return numbers
nums = [1,2,3,4,5,6,7]
print(power(nums))#[1, 4, 9, 16, 25, 36, 49]
print(nums)#[1, 2, 3, 4, 5, 6, 7]
這里的參數(shù)屬于普通類型荸镊,所以原本的nums不會(huì)一起改變
def power(numbers):
numbers = list(numbers)
numbers[3] = 10
return numbers
nums = [1,2,3,4,5,6,7,8]
print(power(nums))#[1, 2, 3, 10, 5, 6, 7, 8]成功將第四個(gè)數(shù)換成了10
函數(shù)名的本質(zhì)是函數(shù)的地址
def fun():
print("hello world")
f = fun
f()
用f()可直接執(zhí)行函數(shù)fun()
閉包
內(nèi)層函數(shù)可以訪問(wèn)外層函數(shù)的值咽斧,但是不能修改
內(nèi)層函數(shù)訪問(wèn)變量時(shí)會(huì)先從自己內(nèi)部查找堪置,如果找不到就會(huì)層層向上查找
def outter():
def inner():
print("hello innner")
return inner
fo = outter()
fo()
閉包的本質(zhì)是函數(shù)的嵌套函數(shù),外層函數(shù)返回內(nèi)層函數(shù)的地址
def outter():
aa= 10
def inner():#說(shuō)明使用的是全局變量张惹,最外層
nonlocal aa
aa -= 1
print(aa)
print(aa)
return inner
fo = outter()
fo()#9
fo()#8
fo()#7
fo()#6
outter()
nonlocal:讓外層的關(guān)鍵字在這一層生效
遞歸:
函數(shù)自己調(diào)用自己舀锨,編寫(xiě)遞歸或循環(huán)時(shí),一般先考慮出口(結(jié)束的條件)問(wèn)題宛逗、
舉個(gè)例子:階乘
def factorial(n):
mm = 1
for num in range(1,n+1):
mm*=num
return mm
print(factorial(5))#120
def factor(n):
if n==1:
return 1
return n*factor(n-1)#是1就返回1坎匿,否則返回n*n-1
print(factor(5))#120
高階函數(shù)
def handle(func,*param):
return func(*param)
def my_sum(*param):
sum = 0
for i in range(len(param)):
sum += param[i]
return sum
print(my_sum(1,2,3,4,6))#16
def my_mul(*param):
mul = 1
for v in param:
mul *=v
return mul
print(handle(my_mul,1,2,3,4,5))#120
func代表函數(shù),param代表參數(shù)
常見(jiàn)的高階函數(shù)
1.map
map(func,inteable)該函數(shù)會(huì)把inteable中的數(shù)據(jù)一次傳遞給func函數(shù)處理雷激,最后把結(jié)果返回
inteable是指可迭代對(duì)象替蔬,可以是一個(gè)數(shù)組
[1,2,3,4,5]-->[1,4,9,16,25]
def power(x):
return x*x
result = map(power,[1,2,3,4,5,6])
for i in result:
#print(i)
print(list(result))#[1, 4, 9, 16, 25, 36]
results = map(lambda x:x*x,[1,2,3,4,5,6,7])
print(list(results))#[1, 4, 9, 16, 25, 36]
2.reduce
reduce(func,inteable)函數(shù):累計(jì)操作,fun函數(shù)必須接收兩個(gè)參數(shù),reduce會(huì)把func的運(yùn)行結(jié)果當(dāng)做一個(gè)參數(shù)
from functools import reduce
l = [1,2,3,4,5]
result1 =reduce(lambda x,y:x*y,l)
print(result1)#120
3.filter
filter(func,inteable)過(guò)濾:根據(jù)函數(shù)func來(lái)過(guò)濾interable
l1 = [1,2,3,4,5,6,7,9,34]
result = list(filter(lambda x:x%2 == 1 ,l1))
print(result)#[1, 3, 5, 7, 9]
將interable中的數(shù)據(jù)傳入func中屎暇,如果函數(shù)返回true承桥,就保留該數(shù),不然就刪去
斐波那契數(shù)列
方法一:遞歸法
def fbnq(n):
if n == 1 or n == 2:
return 1
return fbnq(n - 1) + fbnq(n - 2)
for i in range(1, 10):
print(fbnq(i))
2.for循環(huán)的方法
def fbnq(n):
a = 0
b = 1
if n ==1:
return 1
for i in range(2,n+1):
tmp = a + b
a ,b =b,tmp
return tmp
for i in range(1,10):
print(fbnq(i))