初学python随笔——函数

定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

特性:

  1. 减少重复代码
  2. 使程序变的可扩展
  3. 使程序变得易维护

语法定义

# 不带参
def sayhi():
    print('hi')

sayhi()    # 调用


# 带参
def calc(x,y):
    res = x+y
    return res

c = calc(5,5)
print(c)


# 多个参数返回
def num(x,y):
    return x,y

c = num(4,5)
print(c)

  

形参与实参关系

形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

默认参数

# 函数中添加默认参数数值,调用时不填写,返回默认
def num(x=2):
    return x

c = num()
print(c)

c = num(4)
print(c)

  

默认参数乱用的坑

def add_end(L=[]):
    L.append('End')
    return L

# 正常调用
>>>add_end([1,2,3])
[1,2,3,'End']

# 第一次使用默认参数
>>>add_end()
['End']

# 第二次调用默认参数
>>>add_end()
['End','End']

'''
Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,
则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
'''

# 修改上面函数使之正常 
def add_end(L=None): 
    if L is None: 
        L = [] 
    L.append('End'] 
    return L    

可变参数,我更喜欢叫他为元组参数  

# 用于接收不确定会接收多少参数时使用
def message(name, age, *args):
    print(name, age, args)


# 不带args调用时,会返回一个()
>>>message('Demo', '18')
Demo 18 ()

# 传入多个信息,会将信息传成元组
>>>message('Demo', '18', 'red', 180)
Demo 18 ('red', 180)

 

关键字参数,我更喜欢叫他为字典参数

# 同上面一样,也接收多个参数,不过这个是以字典形式返回,并且需要加上key
def message(name, age ,**kwargs):
    print(name, age, kwargs)


# 不带kwargs调用时,会返回一个{}
>>>message('Demo', '18')
Demo 18 {}

# 传入多个信息,会将信息传成字典
>>>message('Demo', 18, sex = 'Male', color = 'Red')
Demo 18 {'sex': 'Male', 'color': 'Red'}

  

变量作用域(从上往下查找顺序)

L  局部作用域

E  必报函数外的函数中

G  全局作用域

B  内建作用域

嵌套函数

name = 'Demo'

def change_name():
    name2 = 'Demo2'

        def change_name2():
            name3 = 'Demo3'
            print(name)

    change_name2()
    print(name)


change_name()

# 打印的name顺序为 Demo3  Demo2  该函数既考察了作用域和函数调用顺序

  

递归函数

# 如果一个函数在内部调用自身本身,这个函数就是递归函数,做个1x2x3x4.....
def fact(n)
    if n =1:
        return 1
    return n*fact(n-1)

'''
查看fact(5)的计算过程
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120
'''

  

尾递归

# 尾递归是把递归做优化,但是在python中即使做了优化,也会和递归一样出现栈溢出情况

def fact(n):
    return fact_iter(n, 1)

def fact_iter(num, product):
    if num == 1:
        return product
    return fact_iter(num - 1, num * product)

'''
return fact_iter(num - 1, num * product)仅返回递归函数本身,num - 1和num * product在函数调用前就会被计算,不影响函数调用。

fact(5)对应的fact_iter(5, 1)的调用如下:

===> fact_iter(5, 1)
===> fact_iter(4, 5)
===> fact_iter(3, 20)
===> fact_iter(2, 60)
===> fact_iter(1, 120)
===> 120
'''

  

使用递归函数做一个二分查找

data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
 
 
def binary_search(dataset,find_num):
    print(dataset)
 
    if len(dataset) >1:
        mid = int(len(dataset)/2)
        if dataset[mid] == find_num:  #find it
            print("找到数字",dataset[mid])
        elif dataset[mid] > find_num :# 找的数在mid左面
            print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
            return binary_search(dataset[0:mid], find_num)
        else:# 找的数在mid右面
            print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
            return binary_search(dataset[mid+1:],find_num)
    else:
        if dataset[0] == find_num:  #find it
            print("找到数字啦",dataset[0])
        else:
            print("没的分了,要找的数字[%s]不在列表里" % find_num)
 
 
binary_search(data,66)

匿名函数  

# 匿名函数就是不需要显式的指定函数 使用lambda

# 普通代码
def calc(n):
    return n**n
print(calc(10))

# 匿名函数
calc = lambda n:n**n


# 匿名函数主要是和其他函数搭配使用,如下
res = map(lambda x:x**2,[1,5,7,4,8])
for i in res:
    print(i)

  

  

猜你喜欢

转载自www.cnblogs.com/CrazyDemo/p/9429217.html