五、Python函式之基礎

很难通透發表於2024-07-16

全域性變數與區域性變數

頂頭,沒有任何縮排就是全域性變數
函式里的變數是區域性變數
如果在函式里使用 global全域性變數,則可以改變全域性變數。
如果沒有global全域性變數,呼叫全域性變數的時候,只能讀取,無法重新賦值
nonlocal 取上一級變數
書寫規範
全域性變數大寫
區域性變數小寫

遞迴函式

歸函式特性
一個函式呼叫自己
1.必須有一個明確的結束條件
2.每進入更深層次遞迴時,問題規模相比上一次遞迴都應有所減少
3.遞迴效率不高,遞迴層次過多會導致棧溢位。

person_list = ['alex','wupeiqi','linhaifeng','zsc']

def ask_way(person_list):
    print('-'*60)
    if len(person_list) == 0:
        return '根本沒人知道'
    person = person_list.pop(0)

    if person == 'linhaifeng':
        return '%s說:我知道,老男孩就在....' % person

    print('hi 你好[%s],敢問路在何方'%person)
    print('%s回答道:我不知道,但念你慧眼識豬,你等著,我幫你問問%s...'%(person,person_list))

    res = ask_way(person_list)
    print('%s問的結果是:%s'%(person,res))
    return res
res = ask_way(person_list)
print(res)
#>>>
------------------------------------------------------------
hi 你好[alex],敢問路在何方
alex回答道:我不知道,但念你慧眼識豬,你等著,我幫你問問['wupeiqi', 'linhaifeng', 'zsc']...
------------------------------------------------------------
hi 你好[wupeiqi],敢問路在何方
wupeiqi回答道:我不知道,但念你慧眼識豬,你等著,我幫你問問['linhaifeng', 'zsc']...
------------------------------------------------------------
wupeiqi問的結果是:linhaifeng說:我知道,老男孩就在....
alex問的結果是:linhaifeng說:我知道,老男孩就在....
linhaifeng說:我知道,老男孩就在....

函式作用域

name = 'alex'

def foo():
    name = 'hg'
    def bar():
        name = 'lg'
        def tt():
            return name
        return tt
    return bar

foo = foo()()()    #foo()執行第一個函式,返回bar == foo(),然後foo()() == bar(),接著執行bar().....
print(foo)

匿名函式lambda

lambda x:x+1       #  函式形式  lambda 形參 : 返回值
a = lambda x:x+1
print(a(10)) #11
name  = 'lghg'
def change_name(x):
    return name+'_nb'
res = change_name(name)
print(res) #>>>lghg_nb

f = lambda x:name+'_nb'
res = f(name)
print(res)#>>>lghg_nb
# print((lambda x:name+'_nb')(name))  #更加簡潔

f = lambda x,y,z:x+y+z
res = f(1,2,3)
print(res) #>>>6

函數語言程式設計

函式式 = 程式語言定義的函式+數學意義的函式
高階函式:1.函式接收的引數是一個函式名 2。返回值中包含函式

#非函式式
a = 1
def text():
    global a
    a += 2
    return a


#函式式
n = 1
def func(n):
    return n+1


# 高階函式:1.函式接收的引數是一個函式名 2。返回值中包含函式
def foo(n):
    print(n)
def bar(name):
    print(name)
foo(bar("hg"))

內建函式

map函式:重點
map函式 表示式:map(func,可迭代物件), 功能:把可迭代物件用for迴圈的方式進行功能函式處理,得到的結果是一個列表地址,位置以及個數與原來一樣

點選檢視程式碼
num1 = [1,2,3,4,5,6,7,8,9]
#執行每個數加1
def add_1(x):
    return x+1
lambda x:x+1

def reduce_1(x): #執行每個數減1
    return x-1

lambda x:x-1
def mab_text(func,array): #使用func(i)是為了不把函式寫死,這樣這個函式就可以呼叫其他功能函式
    res=[]
    for i in array:
        ret=func(i) #add_1(i)/(lambda x:x+1)(i)/reduce_1(i)/(lambda x:x-1)(i)
        res.append(ret)
    return res
print(mab_text(add_1,num1))
print(mab_text(lambda x:x+1,num1))
print(mab_text(reduce_1,num1))
print(mab_text(lambda x:x-1,num1))

#map函式可以使上面的功能更加簡潔
#map函式  map(func,可迭代物件) 功能:把可迭代物件用for迴圈的方式進行功能函式處理,得到的結果是一個列表地址,位置以及個數與原來一樣
res = map(lambda x:x+1,num1)
print("內建函式map,處理結果",res) #<map object at 0x0000018981841750> 地址
print(list(res)) #[2, 3, 4, 5, 6, 7, 8, 9, 10]

print(list(map(reduce_1,num1)))#[0, 1, 2, 3, 4, 5, 6, 7, 8]

lh = 'hjgjkcgj' #全部轉換成大寫
print(list(map(lambda x:x.upper(),lh))) #['H', 'J', 'G', 'J', 'K', 'C', 'G', 'J']

filter函式 :重點
filter函式 把迭代物件在功能函式進行for迴圈,判斷為True則輸出,判斷為False則過濾,刪除

點選檢視程式碼
movie_people = ['sb_jhj','sb_kk','sb_jj','hg','lg','sb_jhj']

"""
濾除不要的人
"""
res = []
for person in movie_people:            #不用函式
    if  not person.startswith('sb'):
        res.append(person)
print(res) #['hg', 'lg']

def filter_movie(array): #用函式
    ret = []
    for i in array:
        if not i.startswith('sb'):
            ret.append(i)
    return ret
print(filter_movie(movie_people)) #['hg', 'lg']

def sb_show(n):
    return n.startswith('sb')

def filter_movie(func,array):
    ret = []
    for i in array:
        if not func(i): #使用func(i)是為了不把函式寫死,這樣這個函式就可以呼叫其他功能函式
            ret.append(i)
    return ret
print(filter_movie(sb_show,movie_people)) #['hg', 'lg']

#終極版本
res = filter_movie(lambda x:x.startswith("sb"),movie_people)
print(res) #['hg', 'lg']

#filter函式  把迭代物件在功能函式進行for迴圈,判斷為True則輸出,判斷為False則過濾,刪除
movie_people = ['sb_jhj','sb_kk','sb_jj','hg','lg','sb_jhj']
print(filter(lambda x:x.startswith("sb"),movie_people)) #<filter object at 0x000001B1D28A1FF0> 記憶體地址
print(list(filter(lambda x:x.startswith("sb"),movie_people)))#['sb_jhj', 'sb_kk', 'sb_jj', 'sb_jhj'] #如果是以sb開頭則為真,即輸出
print(list(filter(lambda x:not x.startswith("sb"),movie_people)))#['hg', 'lg']
print(list(map(lambda x:not x.startswith("sb"),movie_people)))#[False, False, False, True, True, False]


**reduce函式** reduce 函式 把整個迭代物件壓縮為一個值
from functools import reduce #必須要有
print(reduce(lambda x,y:x*y,num_1)) #362880

zip函式

#zip #一一對應,形成元組,再組成列表
print(list(zip(('a','b','c'),(1,2,3))))#[('a', 1), ('b', 2), ('c', 3)] 
print(list(zip(('a','b','c'),(1,2,3,4)))) #[('a', 1), ('b', 2), ('c', 3)]
print(list(zip(('a','b','c','d'),(1,2,3,4))))#[('a', 1), ('b', 2), ('c', 3)]

p = {'name':'hg','age':23,'hoppy':'mv'}
print(list(zip(p.keys(),p.values()))) #[('name', 'hg'), ('age', 23), ('hoppy', 'mv')]

max、min函式及高階使用
max 取最大值 min取最小值

高階使用:
1.max函式處理的是可迭代物件,相當於一個for迴圈取出每個元素進行比較,注意,不同型別之間不能進行比較
2.每個元素進行比較,是從每個元素的第一個位置依次比較,如果這一位置區分出大小,後面的都不需要比較了,直接得出這兩個元素的大小

age_dic = {'age1':18,'age2':19,'age3':20}
print(max(age_dic.values()))
print(max((zip(age_dic.values(),age_dic.keys())))) #(20, 'age3')

people = [
    {'name':'hg','age':23},
    {'name':'lg','age':18},
    {'name':'mv','age':19}
]

print(max(people, key = lambda dic:dic['age']))#>>>{'name': 'hg', 'age': 23}

sorted函式
sorted排序 本質比較大小,只有同型別才能比較

L = [2,8,6,7,3]
print(sorted(L)) #[2, 3, 6, 7, 8]

people = [
    {'name':'hg','age':23},
    {'name':'lg','age':18},
    {'name':'mv','age':19}
]
print(sorted(people, key = lambda dic:dic['age'])) #[{'name': 'lg', 'age': 18}, {'name': 'mv', 'age': 19}, {'name': 'hg', 'age': 23}]

name = {
    'lg':2000,
    'mv':300,
    'hg':1000
}
print(sorted(name))#['hg', 'lg', 'mv'] 按照keys值直接進行比較
print(sorted(name,key = lambda x:name[x]))#['mv', 'hg', 'lg']
print(sorted(zip(name.values(),name.keys())))#[(300, 'mv'), (1000, 'hg'), (2000, 'lg')]

其他函式

點選檢視程式碼
name = '你好'
print(bytes(name,'utf-8')) #b'\xe4\xbd\xa0\xe5\xa5\xbd'
print(bytes(name,'utf-8').decode('utf-8')) #解碼你好
print(bytes(name,'gbk').decode('gbk')) #你好

#===divmod
print(divmod(7,2)) #取商,餘數>>>(3, 1)

#eval
dic = {"name":'hg'}
dic_str = str(dic)
print(dic_str) #{'name': 'hg'}字串
print(eval(dic_str))#{'name': 'hg'} 字典     #把字串中的資料結構提取出來
a = eval(dic_str) #字串變為字典
print(a['name']) #hg

express = '1+1+23*2'
print(eval(express)) #48 把字串中的表示式進行運算

#hash 可hash的資料型別即不可變資料型別,不可hash的資料型別即可變資料型別
name = 'hg'     #可以用hash判斷所定義的變數,有沒有被修改
print(hash(name))#8023437410973310514
print(hash(name))#8023437410973310514
name = 'lg'
print(hash(name)) #-2793483496824705473

#isinstance 判斷資料型別
print(isinstance('hg',str))#True
print(isinstance(123,int))#True

#ord
print(chr(97)) #a
print(ord('a'))#97
#pow
print(pow(2,3))# 2**3
print(pow(2,3,3))#2**3%3

#round 四捨五入
print(round(3.5)) #4

#切片slice
L = 'lghgkk'
print(L[3:5]) #gk
a = slice(3,5)
print(L[a]) #gk

#sum求和

#type
a= '123'
if type(a) == str:
    a = int(a)
    a +=1
    print(a) #124

#var 用處不大

def test():
    msg = "hello world"
    print(locals())
test() #>>>{'msg': 'hello world'}

def test():
    msg = "hello world"
    print(vars())            #沒有引數和locals()一樣,有引數的時候把物件列印成字典的形式

test() #>>>{'msg': 'hello world'}

相關文章