当前位置: 首页 > article >正文

六、Python —— 函数

文章目录

  • 一、函数基础
    • 1.1、编写函数
    • 1.2、调用函数
    • 1.3、形参和实参
      • 1.3.1、形参的初始化方式
      • 1.3.2、带默认值的形参
    • 1.4、变量的作用域
    • 1.5、嵌套定义函数
    • 1.6、pass 语句
  • 二、参数传递
    • 2.1、值传递
    • 2.2、引用传递
  • 三、return 语句
  • 四、lambda 表达式
  • 五、函数递归


一、函数基础

 Python 中一个典型的函数定义包括以下部分:

  • 关键字 def
  • 函数名称
  • 由 0 个或多个形参组成的列表
  • 函数体

1.1、编写函数

 一个求阶的函数:

def fact(n):
    res = 1
    for i in range(1, n + 1):
        res *= i
    return res

1.2、调用函数

函数的调用完成两项工作:

  1. 用实参初始化函数对应的形参
  2. 将控制权转移给被调用的函数
print("我们要计算5的阶乘,答案是:")
print(fact(5))  # 输出 120
print("计算结束啦!")

1.3、形参和实参

实参 指调用函数时传入的变量或常量,形参 指定义函数时参数列表里的变量,形参列表可以为空。

1.3.1、形参的初始化方式

 调用函数时会 用实参去初始化形参,初始化的 顺序 有两种:

  • 第一种是 用位置实参 来初始化形参。顾名思义,实参会按位置关系来初始化形参,第一个实参初始化第一个形参,第二个实参初始化第二个形参,依此类推。形参和实参的个数必须匹配。例如:
def f(a, b, c, d):
    print("a =", a, end=", ")
    print("b =", b, end=", ")
    print("c =", c, end=", ")
    print("d =", d)

f(1, True, "Python", 4.2)  # 输出 a = 1, b = True, c = Python, d = 4.2
f(1, True, "Python", 4.2, 3)  # 会报错,因为实参个数多于形参
f(1, True, "Python")  # 会报错,因为实参个数少于形参
  • 第二种是 用关键字实参 来初始化形参。此时实参不再按位置关系来初始化形参,而是按变量名初始化。例如:
def f(a, b, c, d):
    print("a =", a, end=", ")
    print("b =", b, end=", ")
    print("c =", c, end=", ")
    print("d =", d)
    
f(b=1, c=True, a="Python", d=4.2)  # 输出 a = Python, b = 1, c = True, d = 4.2
  • 两种方式也可以 混合使用,但是 位置实参一定要放到关键字实参 之前。也就是说,位置实参只能初始化前若干个实参。例如:
def f(a, b, c, d):
    print("a =", a, end=", ")
    print("b =", b, end=", ")
    print("c =", c, end=", ")
    print("d =", d)
    
f(1, 2, d="Python", c=4.2)  # 输出 a = 1, b = 2, c = 4.2, d = Python
f(1, b=3, "Python", d=4.2)  # 会报错,因为位置实参位于关键字实参后面了。

1.3.2、带默认值的形参

 形参也可以 设置默认值,但所有带默认值的形参必须是 最后几个。当某些形参没有被初始化时,这些形参会使用默认值。例如:

def f(a, b, c=3, d="Python"):
    print("a =", a, end=", ")
    print("b =", b, end=", ")
    print("c =", c, end=", ")
    print("d =", d)

f(1, 2)  # c和d没有被初始化,采用默认值。输出 a = 1, b = 2, c = 3, d = Python
f(1, b=2, d="AcWing")  # c没有被初始化,采用默认值。输出 a = 1, b = 2, c = 3, d = AcWing

可以看到,位置实参和关键字实参中间是可以省略实参的,这种情况就取默认值

1.4、变量的作用域

函数内 定义的变量为 局部变量,只能在函数内部使用。

 当需要修改用 全局变量 时,需要用 global 关键字在函数内声明全局变量。例如:

x = 1

def f():
    global x  # 在函数内声明全局变量
    x = 666
    y = 777
    print(x, y)

f()  # 输出 666 777
print(x)  # 会发现全局变量x也被修改了
print(y)  # 会报错,因为y是局部变量,函数外无法使用

1.5、嵌套定义函数

 函数内部也可以定义函数。函数内部定义的函数,作用域为外层函数。例如:

def f():
    def g(x):  # 定义函数g()
        x += 1
        print(x)
    g(5)  # 调用函数g()


f()  # 输出6

1.6、pass 语句

 当函数定义完但还不想实现时,可以用 pass 占位符,来避免出现语法错误。例如:

def f():
    pass

二、参数传递

2.1、值传递

intfloatboolstr 等采用 值传递值传递 指的是 实参 传递给 形参 的是 数值,而不是 变量空间
 将 实参的 初始值 拷贝给 形参。此时,对形参的改动 不会影响 实参的初始值。例如:

def f(y):
    y = 5
    print(y)

x = 10
f(x)
print(x)  # 会发现x的值没变

2.2、引用传递

列表 采用的就是 引用传递引用传递 指的是 实参 将自己的 变量空间 传递给了 形参
 将 实参的 引用 传给 形参,此时 对形参的修改 会影响 实参的初始值。例如:

def f(b):
    for i in range(len(b)):
        b[i] += 1

a = [0, 1, 2, 3, 4]
f(a)
print(a)  # 会发现列表a中的每个数加了1

三、return 语句

return 语句终止当前正在执行的函数并将控制权返回到调用该函数的地方,并返回结果。例如:

def f(x):
    if x == 1:
        return  # 不写返回值时,会返回 None
    if x == 2:
        return 3  # 返回一个变量
    if x == 3:
        return 4, 5  # 返回多个变量

a = f(1)
b = f(2)
c, d = f(3)
e = f(4)  # 没写return时,也会返回None
print(a, b, c, d, e)  # 输出 None 3 4 5 None

四、lambda 表达式

lambda 关键字可以创建 匿名函数,目的是为了简化代码。lambda 函数的语法格式如下。其中,arguments 指的是 参数expression 指的是 函数的返回值 (不用写 return)

lambda arguments: expression

 有些函数可能会 用函数作为参数 (因为函数和变量实际上是一样的),这种情况的 第一种处理方法 就是,先将函数定义出来,然后将函数传进去。例如:

def foo(a, b, g):
    g()
    return a + b

def f():
    print("I'm called!")

s = foo(3, 4, f)

 上面第一种处理方法意味着需要占用一个函数名。如果不想占用一个函数名,则可以使用 匿名函数 (lambda),例如:

def foo(a, b, g):
    g()
    return a + b

s = foo(3, 4, lambda: print("I'm called!"))

 匿名函数也可以 传入参数,例如:

def foo(a, b, g):
    g(1, 2)
    return a + b

s = foo(3, 4, lambda x, y: print("I'm called %d %d!" % (x, y)))
print("s = ", s)
"""output
I'm called 1 2!
s =  7

"""

 常与 sort() 函数配合使用,sort() 默认 先根据第一个元素进行比较,再根据第二个元素进行比较,如果希望先根据第二个元素进行比较,且不用 lambda,则需要这样写:

pairs = [[1, "one"], [2, "two"], [3, "three"], [4, "four"]]

def compare(pair):
    return pair[1]

pairs.sort(key=compare)  # 每个元素使用第二个变量比较大小
print(pairs)  # 输出:[[4, 'four'], [1, 'one'], [3, 'three'], [2, 'two']]

 我们可以用 lambda 替换 compare 函数:

pairs = [[1, "one"], [2, "two"], [3, "three"], [4, "four"]]

pairs.sort(key=lambda pair: pair[1])  # 每个元素使用第二个变量比较大小
print(pairs)  # 输出:[[4, 'four'], [1, 'one'], [3, 'three'], [2, 'two']]

注意,lambda 不能写 return,直接将返回值写在里面就自动视为 return


五、函数递归

 在一个函数内部,也可以调用函数自身。这种写法被称为 递归
 写递归函数可以从 集合 的角度来思考。理解递归函数的执行顺序可以用 的形式来思考。
 例如,求解斐波那契数列第 𝑛 项可以采用如下写法:

def fib(n):
    if n <= 2:
        return 1
    return fib(n - 1) + fib(n - 2)


print(fib(6))  # 输出 8

http://www.kler.cn/a/418535.html

相关文章:

  • 龙蜥 Linux 安装 JDK
  • CentOS使用chrony服务进行时间同步源设置脚本
  • C++练级计划-> 《IO流》iostream fstream sstream详解
  • 2024.11.29(单链表)
  • 爬取boss直聘上海市人工智能招聘信息+LDA主题建模
  • winform跨线程更新界面
  • CondaValueError: Malformed version string ‘~‘: invalid character(s).
  • 猜一个0到10之间的数字 C#
  • HHO-CNN-BiGRU-Attention哈里斯鹰优化算法卷积神经网络结合双向门控循环单元时间序列预测,含优化前后对比
  • 深度学习周报(11.25-12.1)
  • 【Go】-调度器简介
  • 论文笔记-WWW2024-ClickPrompt
  • qt QStyle详解
  • 网络安全(三):网路安全协议
  • 单片机学习笔记 13. 定时/计数器_计数
  • 无法找到“M_PI”,文件夹树目录实现拖拽打开文件
  • 企业级日志中心(ELK)
  • 对于部署 React 应用,我推荐以下方案(20241127使用方案1Nginx+PM2):
  • 打字指法和键盘按键功能简介
  • 【51单片机】程序实验910.直流电机-步进电机
  • 探索嵌入式硬件设计:揭秘智能设备的心脏
  • 地级市单要素能源利用效率及能源消耗总量(2000-2022年)
  • openjdk17 jvm堆空间分配
  • 关于VNC连接时自动断联的问题
  • 【前端入门】行内元素和块级元素
  • 【0x0001】HCI_Set_Event_Mask详解