python中函数设计与使用

函数设计思想

将可能需要反复执行的代码封装为函数,并且在需要该功能的地方进行调用,这样不仅可以实现代码复用,更重要的是可以保证代码的一致性,只需要修改该函数代码,则所有调用均受到影响。

函数形式

def 函数名([参数列表]):
'''注释'''
函数体

注意事项

函数形参不需要声明类型,也不需要指定函数返回值类型,即使该函数不需要接收任何参数,也必须保留一对空的圆括号(括号后面的冒号也不能少),函数体相对于def关键字必须保持一定的空格缩进。Python允许嵌套定义函数。


函数定义实例

函数递归调用

函数的递归调用是函数调用的一种特殊情况,函数调用自身,自己再调用自己,......,当某个条件得到满足的时候就不再调用,然后再一层一层的返回,直到该函数第一次调用的位置。

递归调用

注意:是函数自身调用自身,当某个条件达到要求后,再一层一层返回。

参数传递的序列解包

传递参数时,可以通过在实参序列前加一个星号将其解包,然后传递给多个单变量形参。

>>> def demo(a, b, c):
    print(a+b+c)

>>> seq = [1, 2, 3]
>>> demo(*seq)
6
>>> tup = (1, 2, 3)
>>> demo(*tup)
6

如果函数实参是字典,可以在前面加两个星号进行解包,等价于关键参数。

>>> def demo(a, b, c):
    print(a+b+c)
>>> dic = {'a':1, 'b':2, 'c':3}
>>> demo(**dic)
6
>>> demo(a=1, b=2, c=3)
6
>>> demo(*dic.values())
6

return语句

return语句用来从一个函数中返回一个值,同时结束函数。对于一下情况,python将认为该函数以return None结束,返回空值:
函数没有return语句;
函数有return语句但是没有执行到;
函数有return但是没有返回任何值。
在调用函数或对象方法时,一定要注意有没有返回值,这决定了该函数或方法的用法。

>>> a_list = [1, 2, 3, 4, 9, 5, 7]
>>> print(sorted(a_list))
[1, 2, 3, 4, 5, 7, 9]
>>> print(a_list)
[1, 2, 3, 4, 9, 5, 7]
>>> print(a_list.sort())
None
>>> print(a_list)
[1, 2, 3, 4, 5, 7, 9]

变量的作用域

变量起作用的代码范围称为变量的作用域,不同作用域内变量名可以相同,互不影响。

局部变量

在函数内部定义的普通变量只在函数内部起作用,称为局部变量。当函数执行结束后,局部变量自动删除,不再可以使用。
局部变量的引用比全局变量速度快,应优先考虑使用
如果局部变量与全局变量具有相同的名字,那么该局部变量会在自己的作用域内隐藏同名的全局变量

全局变量

全局变量可以通过关键字global来定义。这分为两种情况:
1.一个变量已在函数外定义,如果在函数内需要为这个变量赋值,并且要将这个赋值结果反映到函数外,可以在函数内使用global将其声明为全局变量。
2.如果一个变量在函数外没有定义,在函数内部也可以直接将一个变量定义为全局变量,该函数执行后,将增加一个全新的全局变量。

>>> def demo():
    global x
    x = 3
    y = 4
    print(x,y)

>>> x = 5
>>> demo()
3  4
>>> x
3
>>> y
NameError: name 'y' is not defined

变量的作用域范围

def scope_test():
    def do_local():
        spam = "我是局部变量"

    def do_nonlocal():
        nonlocal spam           #这时要求spam必须是已存在的变量
        spam = "我不是局部变量,也不是全局变量"

    def do_global():
        global spam             #如果全局作用域内没有spam,就自动新建一个
        spam = "我是全局变量"

    spam = "原来的值"
    do_local()
    print("局部变量赋值后:", spam)
    do_nonlocal()
    print("nonlocal变量赋值后:", spam)
    do_global()
    print("全局变量赋值后:", spam)

scope_test()
print("全局变量:", spam)

lambda表达式

lambda的一些概括

lambda表达式可以用来声明匿名函数,也就是没有函数名字的临时使用的小函数,尤其适合需要一个函数作为另一个函数参数的场合。也可以定义具名函数。
lambda表达式只可以包含一个表达式,该表达式的计算结果可以看作是函数的返回值,不允许包含复合语句,但在表达式中可以调用其他函数。

lambda表达式范例

>>> f = lambda x, y, z: x+y+z        #可以给lambda表达式起名字
>>> f(1,2,3)                         #像函数一样调用
6
>>> g = lambda x, y=2, z=3: x+y+z    #参数默认值
>>> g(1)
6
>>> g(2, z=4, y=5)                   #关键参数
11
>>> L = [(lambda x: x**2),
         (lambda x: x**3),
         (lambda x: x**4)]
>>> print(L[0](2),L[1](2),L[2](2))
4 8 16
>>> D = {'f1':(lambda:2+3),
         'f2':(lambda:2*3),         
         'f3':(lambda:2**3)}
>>> print(D['f1'](), D['f2'](), D['f3']())
5 6 8
>>> L = [1,2,3,4,5]
>>> print(list(map(lambda x: x+10, L)))        #模拟向量运算
[11, 12, 13, 14, 15]
>>> L
[1, 2, 3, 4, 5]
>>> data = list(range(20))           #创建列表
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

>>> import random
>>> random.shuffle(data)             #打乱顺序
>>> data
[4, 3, 11, 13, 12, 15, 9, 2, 10, 6, 19, 18, 14, 8, 0, 7, 5, 17, 1, 16]

>>> data.sort(key=lambda x: x)       #和不指定规则效果一样
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

>>> data.sort(key=lambda x: len(str(x))) #按转换成字符串以后的长度排序
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

>>> data.sort(key=lambda x: len(str(x)), reverse=True)    #降序排序                                      
>>> data
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#注意:在这里,0-9的长度是一样的,10-19的长度是一样的。故10-19排前面,0-9排后面。

一些函数设计案例

逆序

编写函数,接收包含20个整数的列表lst和一个整数k作为参数,返回新列表。处理规则为:将列表lst中下标k之前的元素逆序,下标k之后的元素逆序,然后将整个列表lst中的所有元素再逆序。

def demo(lst,k):
    x = lst[:k]
    x.reverse()
    y = lst[k:]
    y.reverse()
    r = x+y
    r.reverse()
    return r

lst = list(range(1,21))
print(demo(lst,5))

斐波那契数列

编写函数,接收整数参数t,返回斐波那契数列中大于t的第一个数。

def demo(t):
    a, b = 1, 1
    while b

你可能感兴趣的:(python中函数设计与使用)