python基礎-函數02

#  **************  函數  ********************

#位置參數、可變參數、關鍵字參數、命名關鍵字參數、 關鍵字參數
# 1.位置參數、計算x^2的函數x 就是位置參數
def power(x):
    return x*x
print("兩個數的平方和:",power(20))
# 2.默認參數 b=2 就是默認參數
def power(a,b=2):
    s = 1
    while b >  0:
        s = s * a
        b = b - 1
    return s
print("5的2次方:",power(5,2)) # ==> 5的2次方: 25
print("6的2次方:",power(2)) # ==> 6的2次方: 4
print("6的3次方:",power(6,3)) # ==> 6的3次方: 216
print("6的1次方:",power(6,1))  # ==> 6的3次方: 6
# 3.可變參數:可變參數就是傳入的參數個數是可變的,能夠是1個、2個到任意個,還能夠是0個 爲了使參數是可變的須要參數前加* 如calc(numbers)  calc(1,2,3) 這麼寫就須要加*
def calc(numbers):
    sum = 0
    for x in numbers:
        sum += x
    return sum
print("1~100的和:",calc(range(101))) # ==> 1~100的和: 5050
print("1~10的和:",calc([1,2,3,4,5,6,7,8,9,10])) # ==> 1~10的和: 55
def test(L = []):
    L.append("End")
    return L
print(test()) # ==> ['End']
print(test()) # ==> ['End', 'End']
print(test([1,2,3])) # ==> [1, 2, 3, 'End']
print(test()) # ==> ['End', 'End', 'End']
# 備註:當調用test函數的時候若是傳入爲空咱們能夠發現結果就會發生變化,緣由是test函數定義的時候指向了一個空的list,若是傳入不爲空的list那麼L會指向傳入的list而後執行test的函數內容最後返回,此時若是傳入爲空那麼L仍然指向空的list此時執行test函數拼接"End",此時L的默認參數就再也不爲空了,而是有一個元素爲"End"的list,一次類推,因此默認參數必定要選擇不可變對象
# 4.直接把list或者tuple當作參數寫入很不方便,咱們能夠以*list/tuple當作參數寫入同時定義函數的地方的參數也要進行修改,def cals(*numbers)
def calcc(*numbers):
        sum = 0
        for x in numbers:
                sum += x
        return sum
numberss = [1,2,4]
print("輸出*list/tuple爲參數的結果:",calcc(*numberss))# *numberss表示把nums這個list的全部元素做爲可變參數傳進去 # ==> 輸出*list/tuple爲參數的結果: 7
# 5.關鍵字參數  可變參數容許你傳入0個或任意個參數,這些可變參數在函數調用時自動組裝爲一個tuple。而關鍵字參數容許你傳入0個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝爲一個dict。eg:
def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)
person(23,34) # ==> name: 23 age: 34 other: {}
person("gfengwei",20,agee=20) # ==> name: gfengwei age: 20 other: {'agee': 20}
# 5.1 擴展函數使用
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra) #備註:**extra表示把extra這個dict的全部key-value用關鍵字參數傳入到函數的**kw參數,kw將得到一個dict,注意kw得到的dict是extra的一份拷貝,對kw的改動不會影響到函數外的extra。 ==> name: Jack age: 24 other: {'job': 'Engineer', 'city': 'Beijing'}

# 6. 命名關鍵字 和關鍵字參數**kw不一樣,命名關鍵字參數須要一個特殊分隔符*,*後面的參數被視爲命名關鍵字參數。若是函數定義中已經有了一個可變參數,後面跟着的命名關鍵字參數就再也不須要一個特殊分隔符*了:
# 6.1 關鍵字,在函數的調用者能夠傳入任意不受限制的關鍵字參數,例如上面的city,job咱們能夠任意傳,至於到底傳入了哪些,咱們能夠在函數的內部經過kw進行檢查.
# 以person()函數爲例,咱們但願檢查是否有city和job參數:
def person(name,age,**kw):
    if "city" in kw:
        print("有city參數而後作出處理")
        pass
    if "job" in kw:
        print("有job參數而後作出處理")
        pass
    print("name:",name,"age:",age,'other:',kw)
person("fenwei",24,**extra) # ==> 有city參數而後作出處理 有job參數而後作出處理 name: fenwei age: 24 other: {'job': 'Engineer', 'city': 'Beijing'}

# 6.2備註:命名關鍵字參數必須傳入參數名

# 7.位置參數 默認參數 可變參數 命名關鍵字參數**kw 就是一個擴展dict、命名關鍵字參數

# 順序:必選參數、默認參數、命名關鍵字參數、關鍵字參數

def person(name,age,sex="",*args,**kw):
    print("name:",name,"age:",age,"sex:",sex,"args:",args,"kw:",kw)
person("gz",24) # ==> name: gz age: 24 sex: 男 args: () kw: {}
person("gz",24,"","nongmin","nomoney") # ==> name: gz age: 24 sex: 男 args: ('nongmin', 'nomoney') kw: {}
person("gz",24,"","nongmin","nomoney",city="hangzhou",country="china") # ==> name: gz age: 24 sex: 男 args: ('nongmin', 'nomoney') kw: {'country': 'china', 'city': 'hangzhou'}
args = (1,2,3,4)
kw   = {"a":"123","b":"456"}
person(*args,**kw)
# 8.遞歸函數 遞歸函數須要注意防止棧溢出,遞歸調用的次數過多,會致使棧溢出
def func(n):
    if n == 1:
        return n
    return n * func(n-1)
print("遞歸100階乘:",func(100)) # 1000階乘致使棧溢出

# 8.1解決棧溢出:尾遞歸優化 

# 9.漢諾塔
def hanoi(n,x,y,z):
    if n==1:
        print(x,'-->',z)
    else:
        hanoi(n-1,x,z,y)#將前n-1個盤子從x移動到y上
        hanoi(1,x,y,z)#將最底下的最後一個盤子從x移動到z上
        hanoi(n-1,y,x,z)#將y上的n-1個盤子移動到z上
n=int(input('請輸入漢諾塔的層數:'))
hanoi(n,'x','y','z')
相關文章
相關標籤/搜索