
python基礎(chǔ)
函數(shù)
什么是函數(shù)?為什么要有函數(shù)?函數(shù)存在的意義是什么?
舉一個(gè)小例子,現(xiàn)在有一個(gè)需求需要寫(xiě)一個(gè)學(xué)生管理系統(tǒng),第一步是登陸,之后可以查詢成績(jī)、查詢學(xué)生信息等。但每一個(gè)功能都會(huì)用到登陸功能,如果沒(méi)有函數(shù),則需要每個(gè)功能前面都寫(xiě)登錄功能的代碼,完全一樣的代碼copy過(guò)來(lái),很麻煩,可讀性也不高。
使用函數(shù)可以更高效的開(kāi)發(fā),并且實(shí)現(xiàn)代碼重用。
定義函數(shù)
def 函數(shù)名(形參【可選,沒(méi)有參數(shù)可以不寫(xiě)】):
代碼塊
return【可選,如果沒(méi)有返回值可以不寫(xiě)return】
函數(shù)的調(diào)用
函數(shù)名(實(shí)參)
'''
計(jì)算兩個(gè)數(shù)的和
'''
def figure_sum(a,b):
return a+b
if __name__ == '__main__':
sum = figure_sum(1,2)
print('兩數(shù)之和為:%s'%sum)
python是自上而下執(zhí)行的,所以定義函數(shù)的代碼必須要寫(xiě)在調(diào)用函數(shù)的前面。先定義后調(diào)用
返回值:返回函數(shù)計(jì)算的結(jié)果 return 變量1,變量2。 返回多個(gè)值時(shí)默認(rèn)返回的是元組
函數(shù)嵌套調(diào)?:一個(gè)函數(shù)內(nèi)部嵌套調(diào)用另外一個(gè)函數(shù)
參數(shù)
函數(shù)定義的參數(shù)為形參,用戶調(diào)用函數(shù)時(shí)傳遞的實(shí)際數(shù)據(jù)為實(shí)參
形參
缺省參數(shù)
缺省參數(shù)也叫默認(rèn)參數(shù),在定義函數(shù)時(shí)為參數(shù)提供默認(rèn)值,調(diào)用函數(shù)時(shí)可不傳該參數(shù)的值。??注意缺省參數(shù)需要放在最后,無(wú)論是在函數(shù)定義還是在調(diào)用函數(shù)時(shí),缺省參數(shù)都必須在最后
# name,age,grand,addr 為形參
def get_info(name,age,grand,addr='beijing'):
print(f'name:{name},age:{age},grand:{grand},addr:{addr}')
if __name__ == '__main__':
# zhangsan為位置參數(shù),剩下三個(gè)鍵值對(duì)為關(guān)鍵字參數(shù)
get_info('lisi', 99, 21, 'shanghai')
get_info('zhangsan',90,20)
不定長(zhǎng)參數(shù)
不定長(zhǎng)參數(shù)也叫可變參數(shù),適用于在函數(shù)定義時(shí)不確定傳遞參數(shù)的個(gè)數(shù),其分為元組類型args和字典類型kwargs
*args
調(diào)用函數(shù)時(shí)所有的位置參數(shù)都會(huì)被args變量收集,并將它們按順序封裝為一個(gè)tuple元組
def print_info(*args):
print(args)
if __name__ == '__main__':
print_info('zhangsan',90,20,'shanghai') # ('zhangsan', 90, 20, 'shanghai')
**kwargs
調(diào)用函數(shù)時(shí),需要按照key=value的方式傳遞參數(shù),kwargs會(huì)將參數(shù)封裝為一個(gè)dict字典
def print_info(**kwargs):
print(kwargs)
if __name__ == '__main__':
print_info(name = 'zhangsan', grand = 90, age = 20, addr = 'shanghai') # {'name': 'zhangsan', 'grand': 90, 'age': 20, 'addr': 'shanghai'}
以上兩種不定長(zhǎng)參數(shù)都是組包的方式進(jìn)行傳遞參數(shù)的
實(shí)參
位置參數(shù)
- 位置參數(shù)即直接寫(xiě)數(shù)據(jù),??注意順序和個(gè)數(shù)要和函數(shù)定義時(shí)一致
關(guān)鍵字參數(shù)
- 關(guān)鍵字參數(shù)為key=value形式,如果在一次函數(shù)調(diào)用中既有位置參數(shù)也有關(guān)鍵字參數(shù),則位置參數(shù)要在關(guān)鍵字參數(shù)的前面,關(guān)鍵字參數(shù)之間沒(méi)有順序之分
# name,age,grand,addr 為形參
def get_info(name,age,grand,addr):
print(f'name:{name},age:{age},grand:{grand},addr:{addr}')
if __name__ == '__main__':
# zhangsan為位置參數(shù),剩下三個(gè)鍵值對(duì)為關(guān)鍵字參數(shù)
get_info('zhangsan',grand=90,age=20,addr='beijing')
變量
局部變量
定義在函數(shù)內(nèi)部的變量,只在函數(shù)體內(nèi)部生效。只是臨時(shí)保存數(shù)據(jù),當(dāng)函數(shù)執(zhí)行完時(shí),局部變量會(huì)被銷毀
全局變量
定義在函數(shù)外部的變量,在函數(shù)內(nèi)外都可以被使用。但是如果在函數(shù)內(nèi)要修改全局變量需要加關(guān)鍵字global ,否則并不會(huì)修改全局變量,而是會(huì)重新定義一個(gè)同名的局部變量
拆包
元組
tup = ('zhangsan',20,90,'beijing')
name,age,grand,addr = tup
print(f'name:{name},age:{age},grand:{grand},addr:{addr}'). # name:zhangsan,age:90,grand:20,addr:beijing
字典
dic = {
'name':'zhangsan',
'age':20,
'grand':90,
'addr':'shanghai'
}
name,age,grand,addr = dic
print(name,age,grand,addr) # name age grand addr
字典拆包后得到的是key
遞歸
- 自己調(diào)用自己
- 必須有出口
def recursive_sum(num):
if num == 1:
return 1
result = num + recursive_sum(num-1)
return result
if __name__ == '__main__':
print(recursive_sum(6)) # 21
匿名函數(shù)lambda表達(dá)式
如果函數(shù)邏輯簡(jiǎn)單可以使用lambda表達(dá)式來(lái)簡(jiǎn)化代碼,只需要一行代碼可以替換原有五六行代碼的內(nèi)容,開(kāi)發(fā)更加簡(jiǎn)便
語(yǔ)法
lambda 參數(shù)列表 : 表達(dá)式
lambda可以接收無(wú)數(shù)個(gè)參數(shù)但只能返回一個(gè)表達(dá)式的值
fn = lambda x,y:x+y
print(fn(1,2)) # 3
lambda支持的參數(shù)
無(wú)參數(shù)
# 無(wú)參數(shù)
print((lambda :'你好呀')()) # 你好呀
一個(gè)參數(shù)
# 一個(gè)參數(shù)
print((lambda x:x)('hello world')) # hello world
默認(rèn)參數(shù)
# 默認(rèn)參數(shù)
print((lambda name,age,addr='beijing':'name:%s,age:%d,addr:%s'%(name,age,addr))('zhangsan',20)) # name:zhangsan,age:20,addr:beijing
args
# args
print((lambda *args:args)('zhangsan',20,'beijing')) # ('zhangsan', 20, 'beijing')
kwargs
# kwargs
print((lambda **kwargs:kwargs)(name='zhangsan',age=20,addr='shanghai')) # {'name': 'zhangsan', 'age': 20, 'addr': 'shanghai'}
lambda應(yīng)用
- lambda帶判斷
print((lambda age:'你今年%d歲,你成年了,可以進(jìn)入'%age if age >= 18 else '你今年%d歲,還是未成年,不可以進(jìn)入網(wǎng)吧'%age)(19)) # 你今年19歲,你成年了,可以進(jìn)入
- 排序函數(shù)sort中使用lambda
dics = [
{'name':'zhangsan','age':20,'addr':'shanghai'},
{'name':'lisi','age':21,'addr':'beijing'},
{'name':'wangwu','age':22,'addr':'suzhou'}
]
print(sorted(dics, key=lambda x:x['age'],reverse=True)) # [{'name': 'wangwu', 'age': 22, 'addr': 'suzhou'}, {'name': 'lisi', 'age': 21, 'addr': 'beijing'}, {'name': 'zhangsan', 'age': 20, 'addr': 'shanghai'}]
高階函數(shù)
把函數(shù)作為參數(shù)傳入的函數(shù)即為高階函數(shù)
由于在python中值都是以引用地址來(lái)傳遞的,函數(shù)也不例外。函數(shù)調(diào)用是需要函數(shù)名加小括號(hào)來(lái)進(jìn)行調(diào)用,單純函數(shù)名是可以作為參數(shù)參與其他函數(shù)的定義的
def print_info(str):
print(str)
print_info_new = print_info
print(print_info_new) # <function print_info at 0x7ff17820dca0>
print_info_new('hello world') # hello world
內(nèi)置高階函數(shù)
map
語(yǔ)法:map(func, *iterables)
用途:創(chuàng)建一個(gè)迭代器,使用參數(shù)中的計(jì)算函數(shù)計(jì)算每個(gè)可迭代對(duì)象中的每一個(gè)元素。并將結(jié)果組合成新的迭代器返回。??注意這里返回的是map對(duì)象,需要轉(zhuǎn)換成自己想要的對(duì)象
print(list(map(lambda x,y,z:x+y+z,[1,2,6,9,10],[1,6,2,8,3],[1,9,6,4,3]))) # [3, 17, 14, 21, 16]
reduce
語(yǔ)法:reduce(function, sequence[, initial]
用途:function必須有兩個(gè)參數(shù)。每次function計(jì)算的結(jié)果繼續(xù)和序列的下一個(gè)元素做累加計(jì)算。最終返回計(jì)算的最終結(jié)果
print(functools.reduce(lambda x,y:x+y,[1,4,8,2,19])) # 34
filter
語(yǔ)法:filter(function or None, iterable)
用途:該函數(shù)用于過(guò)濾可迭代對(duì)象, 保留執(zhí)行指定函數(shù)邏輯后為true的元素。如果function為None,則返回為true的項(xiàng)。??注意這里返回的是filter對(duì)象,需要轉(zhuǎn)換成自己想要的對(duì)象
print(list(filter(lambda x:x%2==0,[1,5,8,2,9,3,False]))) # [8, 2, False]
print(list(filter(None,[1,5,8,2,9,3,False]))) # [1, 5, 8, 2, 9, 3]