第五章 python 函数和 lambda 表达式

本文详细介绍了Python中的函数使用,包括定义、调用、文档、返回值及递归。深入探讨了函数参数的多种类型,如关键字参数、默认值、可变参数,并解释了参数传递机制和变量作用域。同时,讲解了局部函数、global和nonlocal关键字的使用。最后,讨论了函数的高级特性及lambda表达式的应用,展示了如何利用lambda简化代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、函数

1. 定义函数

语法格式:
def 函数名(形参列表):
// 由零条到多条可执行语句组成的函数
[return [返回值]]

2. 调用函数

3. 为函数提供文档

help()函数:help(函数名)
__ doc__属性:print(函数名. __ doc __ )

4. 多个返回值

代码如下:

def sum_and_avg(list):
    sum = 0
    count = 0
    for e in list:
        # 如果元素e是数值
        if isinstance(e, int) or isinstance(e, float):
            count += 1
            sum += e
    return sum, sum / count
my_list = [20, 15, 2.8, 'a', 35, 5.9, -1.8]
# 获取sum_and_avg函数返回的多个值,多个返回值被封装成元组
tp = sum_and_avg(my_list)
print(tp)

序列解包功能:

#使用序列解包来获取多个返回值
s, avg = sum_and_avg(my_list)
print(s)
print(avg)

5. 递归函数

代码如下:

def fn(n):
    if n == 0:
        return 1
    elif n == 1:
        return 4
    else:
        #星函数体中调用它自身,就是函数递归
        return 2 * fn(n - 1) + fn(n - 2)
#输出fn(10)的结果
print ("fn(10)的结果是:", fn(10))

二、函数的参数

1. 关键字(keyword)参数

# 定义一个函数
def girth(width, height):
    print("width: ", width)
    print ("height: ", height)
    return 2 * (width + height)
# 传统调用函数的方式,根据位置传入参数值
print(girth(3.5, 4.8))
# 根据关键字参数来传入参数值
print(girth(width = 3.5, height = 4.8))
# 在使用关键字参数时可交换位置
print(girth(height = 4.8, width = 3.5))
# 部分使用关键字参数,部分使用位置参数
print(girth(3.5, height = 4.8))

2. 参数默认值

语法格式:
形参名 = 默认值

代码如下:

# 为两个参数指定默认值
def say_hi(name = "孙悟空", message = "欢迎来到疯狂软件")

3. 参数收集(个数可变的参数)

在形参前面添加一个星号(*),意味着该参数可接收多个参数值,多个参数值被当成元组传入。

代码如下:

# 定义了支持参数收集的函数
def test(a, *books):
    print(books)
    # books被当成元组处理
    for b in books :
        print(b)
    #输出整数变量a的值
    print (a)
# 调用test()函数
test (5, "疯狂iOS讲义", "疯狂Android讲义")

>> ('疯狂iOS讲义', '疯狂Android讲义')
>> 疯狂iOS讲义
>> 疯狂Android讲义
>> 5
#定义了支持参数收集的函数
def test(*books ,num):
    print(books)
    # books被当成元组处理
    for b in books :
        print(b)
    print(num)
#调用testO函数
test ("疯狂iOS讲义", "疯狂 Android讲义", num = 20)

>> ('疯狂iOS讲义', '疯狂 Android讲义')
>> 疯狂iOS讲义
>> 疯狂 Android讲义
>> 20
#定义了支持参数收集的函数
def test(x, y, z=3, *books, **scores):
    print(x, y, z)
    print(books)
    print(scores)
test(1, 2, 3, "疯狂 iOS 讲义", "疯狂Android讲义", 语文=89, 数学=94)
>> 1 2 3
>> ('疯狂 iOS 讲义', '疯狂Android讲义')
>> {'语文': 89, '数学': 94}

test(1, 2, "疯狂 iOS 讲义", "疯狂Android讲义", 语文=89, 数学=94)
>> 1 2 '疯狂 iOS 讲义'
>> ('疯狂 iOS 讲义', '疯狂Android讲义')
>> {'语文': 89, '数学': 94}

test(1, 2, "疯狂Android讲义", 语文=89, 数学=94)
>> 1 2 3
>> ()
>> {'语文': 89, '数学': 94}

4. 逆向参数收集

代码如下:

def foo(name, *nums):
    print ("name 参数:", name)
    print ("nums 参数:", nums)
my_tuple = (1, 2, 3)
#梗用逆向收集,将my^tuple元组的元素传给nums参数
foo('fkif', *my_tuple)

>> name 参数: fkif
>> nums 参数: (1, 2, 3)

5. 函数的参数传递机制

代码如下:

def swap(a , b):
    #下面代码实现a、b变量的值交换
    a, b = b, a
    print("在swap函数里,a的值是", a, ": b的值是", b)
a = 6
b = 9
swap(a , b)
print("交换结束后,变量a的值是", a, ":变量b的值是", b)


>> 在swap函数里,a的值是9 ; b的值是6
>> 交换结束后,变量a的也是6 :变量b的值是9
def swap(dw):
    # 下面代码实现dw的a、b两个元素的值交换
    dw['a'], dw['b'] = dw['b'], dw['a']
    print("在swap()函数里,a元素的值是", dw['a'], ": b 元素的值是", dw['b'])
dw = {'a': 6, 'b': 9}
swap(dw)
print("交换结束后,a 元素的值是", dw['a'], "; b 元素的值是", dw['b'])

>> 在swap()函数里,a元素的值是9 ; b元素的值是6
>> 交换结束后,a元素的值是9 . b元素的值是6

通过上面介绍可以得出如下两个结论:

  • 不管什么类型的参数,在Python函数中对参数直接使用“=”符号赋值是没用的,直接使用“=”符号赋值并不能改变参数。
  • 如果需要让函数修改某些数据,则可以通过把这些数据包装成列表、字典等可变对象,然后把列表、字典等可变对象作为参数传入函数,在函数中通过列表、字典的方法修改它们,这样才能改变这些数据。

6. 变量作用域

在程序中定义一个变量时,这个变量是有作用范围的,变量的作用范围被称为它的作用域。根据定义变量的位置,变量分为两种。

  • 局部变量。在函数中定义的变量,包括参数,都被称为局部变量。
  • 全局变量。在函数外面、全局范围内定义的变量,被称为全局变量。

实际上,Python提供了如下三个工具函数来获取指定范围内的“变量字典”。

  • globals():该函数返回全局范围内所有变量组成的“变量字典”。
  • locals():该函数返回当前局部范围内所有变量组成的"变量字典”。
  • vars(object):获取在指定对象范围内所有变量组成的“变量字典”。如果不传入object参数,vars()和locals。的作用完全相同。

globals()和locals()看似完全不同,但它们实际上也是有联系的,关于这两个函数的区别和联系大致有以下两点。

  • locals()总是获取当前局部范围内所有变量组成的“变量字典",因此,如果在全局范围内(在函数之外)调用locals()函数,同样会获取全局范围内所有变量组成的“变量字典;而globals()无论在哪里执行,总是获取全局范围内所有变量组成的“变量字典”。

  • 一般来说,使用locals()和globals()获取的“变量字典”只应该被访问,不应该被修改。但实际上,不管是使用globals()还是使用locals()获取的全局范围内的“变量字典”,都可以被修改,而这种修改会真正改变全局变量本身:但通过locals()获取的局部范围内的“变量字典”,’即使对它修改也不会影响局部变量。下面程序示范了如何使用locals()、globals()函数访问局部范围和全局范围内的“变量字典"。

代码如下:

def test():
    age = 20
    # 直接访问age局部变量
    print(age)  # 输出20
    # 访问函数局部范围内的“变量数组"
    print(locals())  # {'age': 20}
    # 通过函数局部范围内的“变量数组"访问age变量
    print(locals()['age'])  # 20
    # 通过locals函数局部范围内的“变量数组”改变age变量的值
    locals()['age'] = 12
    # 再次访问age变量的值
    print('xxx', age)  # 依然输出20
    # 通过globals函数修改x全局变量
    globals()['x'] = 19
x = 5
y = 20
print(globals())  # {..., 'x': 5, 'y': 20}
# 在全局范围内使用locals函数,访问的是全局变量的“变量数组”
print(locals())  # {..., 'x': 5, 'y': 20}
# 直接访问x全局变量
print(x)  # 5
# 通过全局变量的“变量数组”访问x全局变量
print(globals()['x'])  # 5
# 通过全局变量的“变量数组”对x全局变量赋值
globals()['x'] = 39
print(x)  # 输前 39
# 在全局范围内使用locals函数对x全局变量赋值
locals()['x'] = 996
print(x)  # 输出 99
(1)访问被遮蔽的全局变量

代码如下:

name = 'Charlie'
def test ():
    # 通过globals()函数访问name全局变量
    print(globals()['name']) # Charlie
    name = '孙悟空'
test()
print(name) # Charlie

>> Charlie
>> Charlie
(2)在函数中申明全局变量

代码如下:

name = 'Charlie'
def test ():
    # 声明name是全局变量,后面的赋值语句不会重新定义局部变量
    global name
    #直接访问name全局变量
    print(name) # Charlie
    name = '孙悟空'
test()
print(name) # 孙悟空

>> Charlie
>> 孙悟空

三、局部函数

1. global关键字

定义函数时,在函数内部对函数外的变量进行操作,声明访问全局变量
global name

2. nonlocal关键字

在函数或其他作用域中使用外层(非全局)变量,声明访问局部变量
nonlocal name

代码如下:

# 定义函数,该函数会包含局部函数
def get_math_func(type, nn):
    # 定又一个弄算平方的局部函数
    def square (n):
        return n * n
    # 定义一个计算立方的局部函数6666
    def cube(n):
        return n * n * n
    # 定义一个计算阶乘的局部函数
    def factorial(n):
        result = 1
        for index in range(2, n + 1):
            result *= index
        return result
    # 调用局部函数
    if type == "square":
        return square(nn)
    elif type == "cube":
        return cube(nn)
    else:
        return factorial(nn)
print(get_math_func("square", 3)) # 输出6
print(get_math_func("cube", 3)) # 输出 27
print(get_math_func("", 3)) # 输出 6

四、函数的高级内容

使用函数变量
使用函数作为函数形参
使用函数作为返回值

五、局部函数与lambda表达式

lambda表达式可以在程序中被传递和调用
表达式:lambda [parameter_list(参数)]:表达式
参数可以忽略,单行函数体的函数

代码如下

def get_math_func(type) :
    result=1
    # 该函数返回的是Lambda表达式
    if type == 'square':
        return lambda n: n * n  # ①
    elif type == 'cube':
        return lambda n: n * n * n  # ②
    else:
        return lambda n: (1 + n) * n / 2 # ③
# 调用get_math_func(),程序返回一个嵌套函数
math_func = get_math_func("cube")
print(math_func(5)) # 输出125
math_func = get_math_func("square")
print(math_func(5)) # 输出25
math_func = get_math_func("other")
print(math_func(5)) # 输出15.0

a = lambda x, y: x + y
def add(x, y): return x+ y

函数的简化形式,lambda表达式,可以使程序更加简洁,而且性能更好。
代码如下:

# 传入计算平方的lambda表达式作为参数
x = map(lambda x: x*x , range(8))
print([e for e in x]) # [0, 1, 4, 9, 16, 25, 36, 49]
# 传入计算平方的lambda表达式作为参数
y = map(lambda x: x*x if x % 2 == 0 else 0, range(8))
print([e for e in y]) # [0, 0, 4, 0, 16, 0, 36, 0]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值