注意此篇文章适合基础不好的同学来看,如果是大佬只能作为知识总结,可以去学习更难的内容。祝你学习愉快!
在编程中,函数是一段代码的封装,具有特定的功能,可以被重复调用这段代码。函数使代码更加模块化、易于维护和重用。在Python中,函数是通过 def 关键字定义的。
1. 函数的定义
- 函数定义使用 def 关键字,后跟函数名、参数列表(可选)和冒号 :。函数体包罗在缩进块中,表现函数的详细实现。
- 根本语法:
- def function_name(parameters):
- # 函数体
- return value # 可选,返回值
复制代码 - 例子:
- def greet(name):
- print(f"Hello, {name}!")
复制代码 在这个例子中,greet 是函数名,name 是参数。函数体中有一个 print() 函数,用于输出问候信息。
2. 函数的调用
- 函数定义(必须先定义再使用)后,可以通过函数名和传入参数来调用它。
- 例子:
- greet("Alice") # 此处没有考虑返回值
复制代码 这会输出 “Hello, Alice!”。
3. 参数和返回值
- 参数:函数可以担当多个参数,这些参数在函数调用时传入。
- 返回值:函数可以返回一个值给调用者,使用 return 关键字。如果没有 return,函数默认返回 None。Python中的参数和返回值和有些语言不一样,会主动推断它们范例,不必要显式去写。
- 例子:
- def add(a, b):
- return a + b
- result = add(3, 4)
- print(result) # 输出: 7
复制代码 3.1 形参和实参
形参(形式参数)
- 定义:形参是在函数定义时使用的参数。它们是占位符,用于接收函数调用时传递给函数的数据。
实参(实际参数)
- 定义:实参是在函数调用时传递给函数的实际值。它们是传递给函数的详细数据。
形参和实参的关系
- 在函数调用时,实参的值会赋给对应的形参,实参的个数和形参要匹配。形参在函数内部使用,而实参是在函数外部传递的实际数据。
- 例子:
- def add(a, b): # 形参 a 和 b
- return a + b
- result = add(3, 4) # 实参 3 和 4
- print(result) # 输出: 7
复制代码 在这个例子中,a 和 b 是形参,它们在函数 add 的定义中。调用 add(3, 4) 时,实参 3 被传递给 a,实参 4 被传递给 b,然后函数返回它们的和。
3.2 默认参数值
- 在定义函数时,可以为参数指定默认值。如果调用时没有提供该参数,函数会使用默认值。有点类似C++中的缺省参数。
- 例子:
- def greet(name="stranger"):
- print(f"Hello, {name}!")
- greet() # 输出: "Hello, stranger!"
- greet("Bob") # 输出: "Hello, Bob!"
复制代码 3.3. 关键字参数
- 函数调用时,可以使用 参数名=值 的形式指定参数,称为关键字参数。这样可以使参数的顺序不那么紧张。
- 例子:
- def describe_person(name, age):
- print(f"{name} is {age} years old.")
- describe_person(age=30, name="Alice")
- # 输出: "Alice is 30 years old."
复制代码 3.4. 可变参数
- *args:函数可以担当任意数目的位置参数,使用 *args。args 是一个元组,包罗全部传递的位置参数。
- **kwargs:函数可以担当任意数目的关键字参数,使用 **kwargs。kwargs 是一个字典,包罗全部传递的关键字参数。
- 例子:
- def sum_all(*args):
- total = 0
- for num in args:
- total += num
- return total
- print(sum_all(1, 2, 3, 4)) # 输出: 10
- def print_info(**kwargs):
- for key, value in kwargs.items():
- print(f"{key}: {value}")
- print_info(name="Alice", age=30, city="New York")
- # 输出:
- # name: Alice
- # age: 30
- # city: New York
复制代码 4. 函数的作用域
- 局部变量:在函数内部定义的变量是局部变量,只能在函数内部访问。
- 全局变量:在函数外部定义的变量是全局变量,可以在函数内部访问和修改。
- 例子:
- x = 10 # 全局变量
- def change_x():
- global x
- x = 20 # 修改全局变量
- change_x()
- print(x) # 输出: 20
复制代码 它们之间的定名可以重复,如果辩论了以局部的为优先,但是一般不建议这么做。
5. 匿名函数(Lambda 函数)
- 定义:Python 支持一种简短的函数定义方式,称为 lambda 函数。lambda 函数用于创建小型、单行匿名函数。
- 语法:
- lambda arguments: expression
复制代码 - 例子:
- add = lambda x, y: x + y
- print(add(3, 4)) # 输出: 7
复制代码 lambda 函数通常在必要简单函数而不想定名时使用,如在排序、过滤等操纵中。
6. 函数的嵌套与闭包
- 嵌套函数:可以在一个函数内部定义另一个函数。
- 闭包:如果一个内部函数引用了外部函数的变量,而且外部函数的作用域已经结束,那么这个内部函数就被称为闭包。
- 例子:
- def outer_function(msg):
- def inner_function():
- print(msg)
- return inner_function
- greet = outer_function("Hello")
- greet() # 输出: "Hello"
复制代码 7. 链式调用
- # 判定是否是奇数
- def isOdd(num):
- if num % 2 == 0:
- return False
- else:
- return True
-
- result = isOdd(10)
- print(result)
复制代码 链式写法:
把一个函数的返回值, 作为另一个函数的参数, 这种操纵称为 链式调用
8. 函数递归(难点)
递归是一种在编程中常用的技术,它指的是函数调用自身来解决问题。递归通常用于将一个复杂问题分解成较小的相似问题,从而通过解决这些较小问题来解决原问题。这部分可以先跳过,等有了肯定的代码履历后再回来看。
8.1 递归的根本概念
- 定义:递归函数是一个会在其定义内部调用自身的函数。
- 布局:递归一般有两个部分:
- 基准情形(Base Case):用于终止递归的条件,当满意这个条件时,递归停止。
- 递归情形(Recursive Case):函数继续调用自身来解决问题的更小部分。
- 例子:盘算阶乘
- def factorial(n):
- if n == 1: # 基准情形
- return 1
- else:
- return n * factorial(n - 1) # 递归情形
- print(factorial(5)) # 输出: 120
复制代码 在这个例子中,factorial() 函数盘算数字 n 的阶乘。如果 n 是 1,则返回 1(基准情形);否则,函数调用自身盘算 n-1 的阶乘,并将结果乘以 n。
8.2 递归的长处
- 简洁性:递归通常能使代码更加简洁和易于明白,特别是当问题本身具有递归性质时(例如树布局遍历、数学归纳等)。
- 天然表达:递归可以或许天然地表达某些问题的布局,使代码与问题的数学描述更一致。
- 解决复杂问题:递归可以或许轻松解决某些分治问题或与树、图等布局相关的问题。
8.3 递归的缺点
- 性能问题:递归的每次调用都会在内存中保留当前函数的状态,这可能会导致较高的内存斲丧,特别是在递归深度较大的情况下容易导致栈溢出。
- 服从低:有些递归算法可能会重复盘算相同的子问题,导致时间复杂度急剧上升,例如未经优化的斐波那契数列盘算。
- 明白难度:对于不认识递归的人来说,递归的逻辑可能较难明白,特别是当递归深度较深或涉及复杂的条件判定时。
例子:未优化的斐波那契递归函数的服从问题
- # 计算斐波那契数列的第40项
- print(fibonacci(40)) # 运行时间可能非常长
复制代码 由于递归未优化,fibonacci(40) 必要大量重复盘算,服从极低。
8.4 递归的优化
- 记忆化:通过缓存已盘算的结果来避免重复盘算,这种技术被称为记忆化或动态规划。
- 转换为迭代:对于某些递归问题,可以将递归转换为迭代来避免栈溢出问题。
例子:使用记忆化优化斐波那契数列(这部分必要等学习了动态规划部分更好明白)
- def fibonacci_memo(n, memo={}):
- if n in memo:
- return memo[n]
- if n <= 1:
- return n
- memo[n] = fibonacci_memo(n-1, memo) + fibonacci_memo(n-2, memo)
- return memo[n]
- print(fibonacci_memo(40)) # 运行速度显著提升
复制代码 8.5 总结
- 递归是一个强盛的工具,特别适用于分治问题、树布局操纵和天然递归问题。
- 它具有简洁性和天然表达的长处,但也存在性能和内存斲丧的问题。
- 通过优化技术,如记忆化或将递归转化为迭代,可以或许有效改善递归的缺点。
函数是Python编程的核心之一,通过明白和使用函数,你可以编写出模块化、可重用和高效的代码。如果对你有资助不妨点个赞支持一下~
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |