Python基础:函数

注意此篇文章适合基础不好的同学来看,如果是大佬只能作为知识总结,可以去学习更难的内容。祝你学习愉快!

在编程中,函数是一段代码的封装,具有特定的功能,可以被重复调用这段代码。函数使代码更加模块化、易于维护和重用。在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
    

在这个例子中,ab 是形参,它们在函数 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:函数可以接受任意数量的位置参数,使用 *argsargs 是一个元组,包含所有传递的位置参数。
  • **kwargs:函数可以接受任意数量的关键字参数,使用 **kwargskwargs 是一个字典,包含所有传递的关键字参数。
  • 例子
    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)

链式写法:

print(isOdd(10))

把一个函数的返回值, 作为另一个函数的参数, 这种操作称为 链式调用


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编程的核心之一,通过理解和使用函数,你可以编写出模块化、可重用和高效的代码。如果对你有帮助不妨点个赞支持一下~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值