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')
原文地址:https://www.cnblogs.com/gui-zi/p/7009612.html