前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >29.Python函数高级指南:返回值、多值返回、偏函数与递归

29.Python函数高级指南:返回值、多值返回、偏函数与递归

作者头像
全栈若城
发布于 2025-05-11 12:49:31
发布于 2025-05-11 12:49:31
17300
代码可运行
举报
文章被收录于专栏:若城技术专栏若城技术专栏
运行总次数:0
代码可运行

Python return函数返回值

Python中的函数通过return语句返回值给调用者。理解return的工作原理对于编写高效的Python代码至关重要。

基本用法

return语句的基本语法非常简单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 函数名(参数列表):
    # 函数体
    return 返回值

当Python执行到return语句时,函数会立即终止执行并将指定的值返回给调用者。

示例1:返回单个值
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 计算平方(数字):
    结果 = 数字 * 数字
    return 结果

# 调用函数并接收返回值
平方结果 = 计算平方(5)
print(平方结果)  # 输出: 25
示例2:提前返回

return语句可以用于在满足特定条件时提前结束函数执行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 检查年龄(年龄):
    if 年龄 < 0:
        return "年龄不能为负数"
    if 年龄 < 18:
        return "未成年"
    return "成年人"

print(检查年龄(-5))  # 输出: 年龄不能为负数
print(检查年龄(16))  # 输出: 未成年
print(检查年龄(20))  # 输出: 成年人
示例3:不带值的return

如果return语句不带任何值,或者函数没有return语句,函数将返回None

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 无返回值函数():
    print("这个函数没有返回值")
    return

结果 = 无返回值函数()
print(结果)  # 输出: None

注意事项

  1. return语句后的代码不会执行
  2. 一个函数可以有多个return语句,但只有一个会被执行
  3. 可以返回任何类型的数据,包括列表、字典、对象等

Python函数怎样返回多个值?

Python函数可以轻松地返回多个值,这是许多其他编程语言所不具备的特性。

使用元组返回多个值

最常见的方法是通过元组返回多个值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 获取个人信息():
    姓名 = "张三"
    年龄 = 30
    职业 = "程序员"
    return 姓名, 年龄, 职业  # 自动打包为元组

# 调用函数并解包返回值
姓名, 年龄, 职业 = 获取个人信息()
print(f"姓名: {姓名}, 年龄: {年龄}, 职业: {职业}")

# 也可以接收为单个元组
个人信息 = 获取个人信息()
print(个人信息)  # 输出: ('张三', 30, '程序员')
print(个人信息[0])  # 访问第一个值: 张三

使用列表返回多个值

当返回的值数量可能变化时,列表是一个好选择:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 获取成绩单(包含不及格=False):
    所有成绩 = [85, 92, 78, 55, 60, 45, 98]
    if not 包含不及格:
        return [分数 for 分数 in 所有成绩 if 分数 >= 60]
    return 所有成绩

及格成绩 = 获取成绩单()
print(及格成绩)  # 输出: [85, 92, 78, 60, 98]

所有成绩 = 获取成绩单(True)
print(所有成绩)  # 输出: [85, 92, 78, 55, 60, 45, 98]

使用字典返回多个值

当需要为返回的值提供标签时,字典是最佳选择:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 计算统计数据(数字列表):
    return {
        "总和": sum(数字列表),
        "平均值": sum(数字列表) / len(数字列表),
        "最大值": max(数字列表),
        "最小值": min(数字列表),
        "数量": len(数字列表)
    }

统计结果 = 计算统计数据([10, 20, 30, 40, 50])
print(f"平均值: {统计结果['平均值']}")
print(f"最大值: {统计结果['最大值']}")

使用类和对象返回复杂数据

对于更复杂的数据结构,可以使用自定义类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class 学生成绩单:
    def __init__(self, 姓名, 成绩列表):
        self.姓名 = 姓名
        self.成绩列表 = 成绩列表
        self.平均分 = sum(成绩列表) / len(成绩列表)
        self.最高分 = max(成绩列表)

def 生成成绩单(姓名, 成绩列表):
    return 学生成绩单(姓名, 成绩列表)

小明成绩单 = 生成成绩单("小明", [85, 92, 78, 90])
print(f"{小明成绩单.姓名}的平均分是{小明成绩单.平均分}")

Python partial偏函数

偏函数(Partial Function)是Python functools模块中的一个重要功能,它允许我们固定函数的某些参数,从而创建一个新的函数。

基本概念

偏函数的主要用途是:

  • 减少重复代码
  • 提高代码可读性
  • 创建特定场景的专用函数

基本用法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from functools import partial

# 原始函数
def 幂运算(底数, 指数):
    return 底数 ** 指数

# 创建平方函数 - 固定指数为2
平方 = partial(幂运算, 指数=2)

# 创建立方函数 - 固定指数为3
立方 = partial(幂运算, 指数=3)

# 使用偏函数
print(平方(4))  # 输出: 16
print(立方(4))  # 输出: 64

实际应用场景

示例1:简化函数调用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from functools import partial

def 格式化打印(内容, 前缀="", 后缀="", 是否换行=True):
    结果 = f"{前缀}{内容}{后缀}"
    if 是否换行:
        print(结果)
    else:
        print(结果, end="")

# 创建特定格式的打印函数
错误打印 = partial(格式化打印, 前缀="错误: ", 后缀="!", 是否换行=True)
警告打印 = partial(格式化打印, 前缀="警告: ", 后缀=".", 是否换行=True)

错误打印("文件不存在")  # 输出: 错误: 文件不存在!
警告打印("磁盘空间不足")  # 输出: 警告: 磁盘空间不足.
示例2:配合内置函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from functools import partial

# 创建一个只接收十进制数的int函数
二进制转十进制 = partial(int, base=2)
十六进制转十进制 = partial(int, base=16)

print(二进制转十进制("1010"))  # 输出: 10
print(十六进制转十进制("1A"))  # 输出: 26
示例3:配合排序函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from functools import partial

学生列表 = [
    {"姓名": "张三", "年龄": 18, "成绩": 85},
    {"姓名": "李四", "年龄": 17, "成绩": 92},
    {"姓名": "王五", "年龄": 19, "成绩": 78}
]

def 按键排序(列表,):
    return sorted(列表, key=lambda x: x[])

按年龄排序 = partial(按键排序,="年龄")
按成绩排序 = partial(按键排序,="成绩")

print("按年龄排序:")
for 学生 in 按年龄排序(学生列表):
    print(f"{学生['姓名']}: {学生['年龄']}岁")

print("\n按成绩排序:")
for 学生 in 按成绩排序(学生列表):
    print(f"{学生['姓名']}: {学生['成绩']}分")

注意事项

  1. 偏函数不会修改原始函数
  2. 可以固定位置参数和关键字参数
  3. 创建偏函数时未指定的参数在调用时需要提供

从实例出发,攻克Python函数递归

递归是一种函数调用自身的编程技术,适合解决可以分解为相似子问题的任务。

递归的基本结构

一个典型的递归函数包含两个部分:

  1. 基本情况(Base Case) - 不再递归调用的终止条件
  2. 递归情况(Recursive Case) - 函数调用自身的情况
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 递归函数(参数):
    # 基本情况 - 终止递归
    if 终止条件:
        return 基本结果
    
    # 递归情况 - 调用自身
    return 递归函数(新参数)

示例1:计算阶乘

阶乘是递归的经典应用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 阶乘(n):
    # 基本情况
    if n == 0 or n == 1:
        return 1
    
    # 递归情况
    return n * 阶乘(n-1)

print(阶乘(5))  # 输出: 120 (5*4*3*2*1)

递归过程分析:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
阶乘(5) = 5 * 阶乘(4) = 5 * 24 = 120
  阶乘(4) = 4 * 阶乘(3) = 4 * 6 = 24
    阶乘(3) = 3 * 阶乘(2) = 3 * 2 = 6
      阶乘(2) = 2 * 阶乘(1) = 2 * 1 = 2
        阶乘(1) = 1 (基本情况)

示例2:斐波那契数列

斐波那契数列是另一个递归的经典例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 斐波那契(n):
    # 基本情况
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    
    # 递归情况
    return 斐波那契(n-1) + 斐波那契(n-2)

for i in range(10):
    print(f"斐波那契({i}) = {斐波那契(i)}")

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
斐波那契(0) = 0
斐波那契(1) = 1
斐波那契(2) = 1
斐波那契(3) = 2
斐波那契(4) = 3
斐波那契(5) = 5
斐波那契(6) = 8
斐波那契(7) = 13
斐波那契(8) = 21
斐波那契(9) = 34

示例3:递归遍历目录

递归非常适合处理树形结构,如文件系统

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os

def 列出所有文件(目录, 缩进=0):
    # 打印当前目录名
    print(" " * 缩进 + f"📁 {os.path.basename(目录)}")
    
    # 遍历目录中的所有项目
    for 项目 in os.listdir(目录):
        完整路径 = os.path.join(目录, 项目)
        
        # 如果是目录,递归调用
        if os.path.isdir(完整路径):
            列出所有文件(完整路径, 缩进 + 2)
        else:
            # 如果是文件,直接打印
            print(" " * (缩进 + 2) + f"📄 {项目}")

# 使用示例 (替换为实际路径)
# 列出所有文件("/Users/用户名/文档")

递归的优化:记忆化

简单递归在处理大规模问题时可能效率低下。以斐波那契数列为例,可以使用记忆化技术优化:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def 优化斐波那契(n, 记忆={}):
    # 检查是否已计算过
    if n in 记忆:
        return 记忆[n]
    
    # 基本情况
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    
    # 递归计算并存储结果
    记忆[n] = 优化斐波那契(n-1, 记忆) + 优化斐波那契(n-2, 记忆)
    return 记忆[n]

# 比较优化前后的性能差异
import time

n = 35

开始时间 = time.time()
结果1 = 斐波那契(n)
结束时间 = time.time()
print(f"普通递归: 斐波那契({n}) = {结果1}, 耗时: {结束时间-开始时间:.2f}秒")

开始时间 = time.time()
结果2 = 优化斐波那契(n)
结束时间 = time.time()
print(f"优化递归: 斐波那契({n}) = {结果2}, 耗时: {结束时间-开始时间:.2f}秒")

递归的注意事项

  1. 递归深度限制:Python默认限制递归深度为1000,可以通过sys.setrecursionlimit()修改
  2. 栈溢出风险:过深的递归可能导致栈溢出
  3. 性能考虑:某些情况下,循环可能比递归更高效
  4. 尾递归:在函数的最后一步调用自身的递归,某些语言会进行优化(但Python不会)

何时使用递归

递归特别适合以下场景:

  • 问题可以分解为相似的子问题
  • 数据结构是分层或树形的(如文件系统、XML解析)
  • 回溯算法
  • 分治算法(如快速排序、归并排序)

通过这些实例,你应该能够理解递归的基本原理和应用场景,为解决更复杂的问题打下基础。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
敏捷开发并非一味的追求交付速度
自2001年《敏捷宣言》发布以来,敏捷开发(Agile Development)逐渐成为软件工程领域的主流方法论。然而,许多人对敏捷开发的认知仍停留在“快速交付”、“压缩时间”的层面,甚至将其等同于“加班赶工”或“牺牲质量的短期冲刺”。
JanYork_简昀
2025/05/20
1480
敏捷开发并非一味的追求交付速度
敏捷开发七个步骤和Scrum敏捷管理工具
敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。敏捷开发并不追求前期完美的设计、完美编码,而是力求在很短的周期内开发出产品的核心功能,尽早发布出可用的版本。然后在后续的生产周期内,按照新需求不断迭代升级,完善产品。
一只爱生气
2023/09/23
3760
彻底搞懂DevOps是什么,CI/CD是什么,跟敏捷开发有什么关系
从之前到现在,从敏捷开发到CI/CD,再到最近的 DevOps等各种名词层出不穷,一直是大概知道是什么意思没有细究,其实本质上就是各种理念各种想法的进步。今天彻底搞懂他们是什么以及各自之间的关系。
shengjk1
2025/05/16
1180
彻底搞懂DevOps是什么,CI/CD是什么,跟敏捷开发有什么关系
敏捷框架之SAFe6.0(中)
在上一篇文章中敏捷框架之SAFe6.0(上)中,我分享了我参加敏捷课程的初步感受和体验。在这一篇文章中,我想继续深入探讨我从这次课程中学到的敏捷的知识和技能,以及敏捷团队的协作和沟通。希望能够对大家有所启发和帮助。
rainbowzhouj
2023/09/27
6670
敏捷框架之SAFe6.0(中)
关于敏捷开发的思考
刚接触敏捷一个月左右,看各种设计模式、TDD、scrum、xp,但是当别人问到我什么是敏捷开发的时候,还是不知道怎么去回答,所以就想着,是时候理一下这些天学习的关于敏捷的所有,在心里搭一个框架。
刘开心_1266679
2019/02/14
6620
关于敏捷开发的思考
敏捷开发中需求变更频繁,如何有效管理?
在敏捷开发中,需求变更是常见的挑战之一,尤其是在面对快速变化的市场需求和客户反馈时。
不脱发的程序猿
2024/12/06
2900
敏捷开发中需求变更频繁,如何有效管理?
Scrum敏捷开发模式的优势、实践经验及适用企业分享
Scrum敏捷模式是一种灵活、适应性强的开发方法,其核心理念是以短周期、高频率的方式进行项目开发,确保团队能够快速响应变化。
一只爱生气
2023/09/06
6430
腾讯敏捷之道,看我就够了
敏捷软件开发,又称敏捷开发,是一种从1990年代开始逐渐引起广泛关注的新型软件开发方法,是一种能应对快速变化需求的软件开发能力。它们的具体名称、理念、过程、术语都不尽相同,相对于“非敏捷”,更强调程序员团队与业务专家之间的紧密协作、面对面的沟通(认为比书面的文档更有效)、频繁交付新的软件版本、紧凑而自我组织型的团队、能够很好地适应需求变化的代码编写和团队组织方法,也更注重软件开发过程中人的作用。
xiangzhihong
2022/11/30
3920
深入核心的敏捷开发
如何破局? 正如《管理3.0:培养和提升敏捷领导力》所说,所有变革最后的失败都是管理的问题。应该把绩效考核这种管理手段当成『敏捷铁三角』中一角来对待,那就是调整约束
yeedomliu
2021/03/16
1.4K0
深入核心的敏捷开发
干货 | 敏捷开发的持续改进
作者简介 黎娟,去哪儿过程改进总监。15年软件项目管理及过程改进经验,曾先后就职于雅虎中国/阿里巴巴、腾讯、去哪儿网,擅长问题分析以及基于问题驱动的过程改进。 “敏捷”这个词近几年非常火,经常会有人问:“我们应该怎样开始做敏捷?”或者:“能不能来帮我们推一下敏捷?”这种问题我通常都不敢轻易回答——敏捷有很多实践,管理的、工程的都有,但敏捷绝非我们看到的站会、持续集成、TDD等那么简单,真正的敏捷体系是从理念到文化的一次变革。 所以具体到一个团队,究竟为什么要做敏捷,能够多大程度地承受改变所带来的痛苦和风险
携程技术
2018/03/16
1.4K0
干货 | 敏捷开发的持续改进
打造企业级自动化运维平台系列(二):DevOps、CI、CD、CT 详解
一个软件从零开始到最终交付,大概包括以下几个阶段:规划、编码、构建、测试、发布、部署和维护,基于这些阶段,我们的软件交付模型大致经历了以下几个阶段。
民工哥
2024/01/18
3K0
打造企业级自动化运维平台系列(二):DevOps、CI、CD、CT 详解
超有料!万字详解腾讯微服务平台 TSF 的敏捷开发流程
导读 相比传统的应用研发流程,以微服务架构为基础的研发团队更需要和依赖整体流程的敏捷属性。为了帮助更多将要或者正在以微服务为架构的项目,了解和解决诸多敏捷开发流程中的问题,特邀腾讯微服务平台(后简称TSF)产品研发团队部分核心成员,对TSF自身如何落地敏捷开发做相关介绍,并经由笔者整理和输出,希望能对以微服务架构构建的项目起到一定参考作用。 崔凯 腾讯云 CSIG 微服务产品中心产品架构师 多年分布式、高并发电子商务系统的研发、系统架构设计经验,擅长主流微服务架构技术平台的落地和实施 目前专
腾讯云中间件团队
2021/03/24
2.3K0
了解敏捷开发
理论上来说,重构思想和开闭原则是相违背的,但如果一开始没有超强的设计分析和预测变化的能力,用来设计的时间不如花在重构上。【设计终究只能浮于纸上,而实践才能更加真实的发现问题】
Noneplus
2019/09/24
1.4K0
敏捷开发(Agile development)
敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。
PM吃瓜
2019/08/12
1.3K0
敏捷开发(Agile development)
漫画:三分钟了解敏捷开发
在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。
小灰
2022/07/05
2830
漫画:三分钟了解敏捷开发
考过ACP的人都知道这里的门道有多深,探索自动化测试在敏捷开发中的关键作用。
在现代市场竞争日益激烈的背景下,快速响应客户需求、缩短交付周期、提升产品质量已成为产品经理关注的核心。随着敏捷开发方法的广泛应用,自动化测试成为敏捷开发中不可或缺的环节。作为从业者,了解自动化测试如何融入敏捷开发,并有效推动项目按时按质交付,能够显著提升团队的工作效率,确保产品满足市场需求,甚至超出用户预期。敏捷开发和自动化测试的结合是不可忽视的创新。通过敏捷开发,团队可以更快地响应客户需求,而自动化测试为这种快速响应提供了强大的质量保障。帮助产品经理和开发团队理解如何利用这两项技术更高效地交付高质量产品。
不惑
2024/10/28
1500
考过ACP的人都知道这里的门道有多深,探索自动化测试在敏捷开发中的关键作用。
Scrum敏捷开发实施步骤和注意事项
在当今高度变化的时代,软件开发的环境和要求也在不断变化。传统的开发方法往往难以适应这种快速变化,因此,一种新的软件开发方法——敏捷开发逐渐得到了广泛的关注和应用。
一只爱生气
2023/09/10
3390
敏捷开发模式下如何快速提升产品质量
随着敏捷开发模式逐渐走入大众视野,它开始逐步取代了传统的瀑布式开发模式,被越来越多的研发项目团队采用。敏捷开发采用快速迭代,快速发布可用版本的方法,持续输出、持续改进。不同于传统的软件开发模式,敏捷开发模式有着自己鲜明的价值和方法。 但即使实践了敏捷,我们可能还会发现,Bug并没有消失。
敏捷开发
2022/11/02
4820
敏捷开发模式下如何快速提升产品质量
什么是敏捷软件开发?
Scrum是一个框架,在这个框架中,人们可以解决复杂的适应性问题,同时高效、创造性地交付最高价值的产品。它用于管理软件项目、产品或应用程序开发。它的重点是自适应产品开发策略,其中跨职能团队作为一个单位,在2-4周内(Sprint)达到一个共同的目标。它由价值、工件、角色、仪式、规则和最佳实践组成。
增强现实核心技术产业联盟
2020/06/12
1.5K0
什么是敏捷软件开发?
落地敏捷开发的12个建议,打造自定义开发管理模式!
目前软件开发业界已存在多种开发合作模式,各有其特点、适用性和局限性,没有一种开发模式是通用又完美的,可以适用任何组织、任何业务的研发协作。所以每个公司研发组织要根据自身业务特点、自身组织实际情况来采用合适的开发管理模式。
嘉为蓝鲸
2020/04/26
9130
落地敏捷开发的12个建议,打造自定义开发管理模式!
推荐阅读
相关推荐
敏捷开发并非一味的追求交付速度
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验