查看全课大纲(第 27 / 51 节)
- 1.为什么人人都该学点编程?
- 2.计算机与程序设计:你的电脑到底在“想”什么?
- 3.Python 这门语言,到底有什么魔力?
- 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
- 5.如何安装一个更强大的代码编辑器?
- 6.汇率兑换1.0:你的第一个“钱生钱”小程序
- 7.你的第一行代码,藏着哪些秘密?
- 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
- 9.汇率兑换程序,如何让它“聪明”地判断币种?
- 10.汇率兑换程序能一直运行,直到我喊停吗?
- 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
- 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
- 13.怎么用 Python 画一个会动的五角星?
- 14.如何让程序自动画出不同大小的五角星?
- 15.函数自己调用自己,会发生什么?
- 16.用递归画出神奇的分形树
- 17.Python 怎么计算你一天躺着不动能消耗多少热量?
- 18.如何让程序“活”起来,持续为你服务?
- 19.如何让 BMR 计算器更“聪明”?
- 20.当程序遇到“不按套路出牌”的用户怎么办?
- 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
- 22.如何用列表记录每一周的存款?
- 23.如何让程序自己数数?—— 用 for 循环解放你的双手
- 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
- 25.52周存钱挑战:怎么根据日期自动查存款?
- 26.Python 怎么判断一年中的第几天?
- 27.列表 vs 元组:哪个更适合存储月份天数?
- 28.用集合给月份分个队,换个思路算天数
- 29.把月份和天数“锁”在一起:用字典给数据配个对
- 30.Python 怎么判断密码强弱?
- 31.Python 怎么给密码设置“防沉迷”系统?
- 32.Python 怎么把密码保存到文件里?
- 33.Python 怎么读取文件里的密码?
- 34.Python 怎么把密码检查工具“打包”起来?
- 35.Python 怎么把文件操作也“打包”起来?
- 36.计算机怎么“扔骰子”?——用Python模拟随机事件
- 37.如何用 Python 模拟掷两个骰子?
- 38.怎么用 Python 把骰子轨迹画出来?
- 39.骰子点数分布长啥样?用直方图一眼看穿!
- 40.用科学计算库让骰子程序“起飞”
- 41.空气质量指数怎么算?手把手教你写一个AQI计算器
- 42.空气质量指数计算:从零开始,让程序看懂空气
- 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
- 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
- 45.Python 怎么让程序自己判断文件类型?
- 46.如何让程序自己上网查空气质量?
- 47.用美味的汤来解析网页:Beautiful Soup 入门
- 48.如何让爬虫自动抓取全国所有城市的空气质量?
- 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
- 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
- 51.空气质量数据怎么“洗”干净,还能画成图?
列表 vs 元组:哪个更适合存储月份天数?
约 10 分钟
小象实战讲义 · Python 入门:8 个小项目边玩边学
还记得上一节我们做的「日期计算器」吗?我们用一个「元组」来存储每个月的天数。今天我们要做一件特别酷的事:用「列表」替换掉「元组」。听起来只是换个容器?但你会发现,这个小小的改变,让我们的程序变得更灵活、更聪明了!
💡 核心导读
- 本节只做一件事:把存储月份天数的「元组」换成「列表」
- 为什么换:列表可以修改,元组不能修改——这个区别决定了我们写代码的方式
- 会学到:如何写一个判断闰年的函数,让代码更整洁
- 有趣发现:原来列表的「可变性」能让闰年判断变得如此简单
- 最终成果:一个更优雅、更灵活的日期计算器
从臃肿到清爽:先给代码做个「瘦身」
在换容器之前,我们先看看上一节的代码。说实话,它有点「臃肿」——判断闰年的逻辑和计算天数的逻辑混在一起,看着不太舒服。
怎么让它变清爽呢?很简单:模块化!把判断闰年这个独立的功能,单独写成一个函数。
from datetime import datetime
def is_leap_year(year):
"""
判断year是否为闰年
是,返回True
否,返回False
"""
is_leap = False # 先默认不是闰年
# 闰年判断条件:四年一闰,百年不闰,四百年再闰
if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
is_leap = True # 满足条件就改成True
return is_leap # 返回最终判断结果
# 测试一下我们的函数
print("2000年是闰年吗?", is_leap_year(2000)) # 应该是True
print("1900年是闰年吗?", is_leap_year(1900)) # 应该是False
print("2024年是闰年吗?", is_leap_year(2024)) # 应该是True2000年是闰年吗? True
1900年是闰年吗? False
2024年是闰年吗? True看到这个函数的妙处了吗?我们只用了一个变量 is_leap,先默认是 False(不是闰年),如果满足闰年条件就改成 True,最后返回这个变量的值。
这种写法只在函数末尾用一个 return 返回结果(称为「单一出口」),逻辑顺着一条线走下来,初学者读起来很清晰。它和在 if/else 里各写一个 return(提前返回)都是很常见的风格,没有绝对的高下之分;本课程为了方便你理解,统一采用这种单一出口的写法。
列表登场:可变的力量
好了,热身完毕!现在进入正题:用列表替换元组。
还记得元组的特点吗?一旦创建就不能修改。而列表正好相反:可以随时修改。这个区别,在我们处理闰年2月天数时,会带来完全不同的编程思路。
from datetime import datetime
def is_leap_year(year):
"""判断是否为闰年"""
is_leap = False
if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
is_leap = True
return is_leap
# 主程序开始
input_date_str = '2000/03/01' # 原程序用input(),这里用固定值方便演示
input_date = datetime.strptime(input_date_str, '%Y/%m/%d')
year = input_date.year
month = input_date.month
day = input_date.day
# 关键变化在这里!用列表代替元组
days_in_month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
# 如果是闰年,直接把2月的28天改成29天
if is_leap_year(year):
days_in_month_list[1] = 29 # 列表索引从0开始,所以1代表2月
# 计算总天数:前面月份的天数总和 + 当月的天数
days = sum(days_in_month_list[:month - 1]) + day
print(f'{year}年{month}月{day}日是{year}年的第{days}天。')2000年3月1日是2000年的第61天。是不是很酷? 用列表后,处理闰年的逻辑变得超级简单:
- 先创建一个平年的月份天数列表(2月是28天)
- 如果是闰年,直接修改列表:
days_in_month_list[1] = 29 - 然后正常计算天数
对比一下元组的做法:我们需要在计算时额外判断「如果是闰年且月份大于2,就加1天」。列表的方法更直观:我直接把数据改对,后面的计算就不用操心了。
列表 vs 元组:不只是「能不能改」
现在你知道了列表和元组最明显的区别:可变 vs 不可变。但它们的区别不止于此,了解这些能帮你更好地选择用哪个。
# 列表通常存放「相同类型」的数据
month_days_list = [31, 28, 31, 30] # 全是数字,表示顺序(1月、2月...的天数)
# 元组通常存放「不同类型但相关」的数据,表示一个结构
person_info_tuple = ('张三', 25, '北京') # 姓名、年龄、城市,构成一个人的信息
# 当然,Python很灵活,你也可以反着用(但不推荐)
mixed_list = [31, '二月', True] # 能运行,但看着别扭
mixed_tuple = (31, 28, 31) # 能运行,但更适合用列表
print("列表示例:", month_days_list)
print("元组示例:", person_info_tuple)列表示例: [31, 28, 31, 30]
元组示例: ('张三', 25, '北京')简单总结一下:
| 特性 | 列表 (List) | 元组 (Tuple) |
|---|---|---|
| 可变性 | ✅ 可以修改 | ❌ 创建后不能修改 |
| 典型用途 | 相同类型数据的顺序集合 | 不同类型数据的固定结构 |
| 表示什么 | 顺序(如:1月、2月、3月…) | 结构(如:(姓名, 年龄, 城市)) |
| 语法 | 方括号 [] | 圆括号 ()(逗号是关键) |
一个实用的选择原则:
- 如果你的数据需要频繁修改,用列表
- 如果你的数据是固定不变的(比如配置信息、坐标点),用元组
- 如果你不确定,先用列表——以后需要不可变性时再改成元组
完整代码:优雅的日期计算器
让我们把所有的改进整合起来,看看2.0版本的完整代码:
from datetime import datetime
def is_leap_year(year):
"""
判断year是否为闰年
是,返回True
否,返回False
"""
is_leap = False
if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
is_leap = True
return is_leap
def main():
"""
主函数:计算某一天是当年的第几天
"""
# 原程序用 input('请输入日期(yyyy/mm/dd):'),这里用固定值演示
input_date_str = '2012/03/05'
input_date = datetime.strptime(input_date_str, '%Y/%m/%d')
year = input_date.year
month = input_date.month
day = input_date.day
# 使用列表存储月份天数
days_in_month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
# 如果是闰年,修改2月的天数
if is_leap_year(year):
days_in_month_list[1] = 29
# 计算总天数
days = sum(days_in_month_list[:month - 1]) + day
print(f'{year}年{month}月{day}日是{year}年的第{days}天。')
# 运行程序
main()2012年3月5日是2012年的第65天。验证一下:2012年是闰年,1月31天 + 2月29天 + 3月5天 = 65天,完全正确!
思维拓展:如果数据更多呢?
现在想象一下,如果我们要处理的不是12个月,而是:
- 365天的每日天气数据
- 1000个学生的成绩
- 一年中每天的股票价格
用列表就太合适了!你可以随时:
- 添加新数据:
data.append(新值) - 修改错误数据:
data[索引] = 新值 - 删除无效数据:
del data[索引]
这种灵活性在实际编程中非常有用。比如你写了一个游戏,用列表存储玩家的装备,玩家获得新装备就 append(),卖掉装备就删除,更换装备就修改——多方便!
📝 动手练一练
改一改,试一试:把上面的完整代码复制到你的Python环境中,把
input_date_str的值改成你自己的生日,看看你的生日是那年的第几天?列表的威力:假设你要记录一周7天的步数,用列表该怎么写?如果周三你多走了1000步,怎么修改这个列表?
👉 点击查看参考答案
第1题:直接把 input_date_str 改成你的生日日期就行,注意格式要是 yyyy/mm/dd。
# 把你的生日放在这里
input_date_str = '1995/08/20' # 示例:1995年8月20日第2题:用列表记录步数,并修改周三的数据。
# 记录一周步数:周一 ~ 周日
daily_steps = [5000, 6000, 7000, 5500, 8000, 3000, 4000]
print("原始步数:", daily_steps)
# 周三(索引2)多走了1000步
daily_steps[2] += 1000
print("修改后步数:", daily_steps)
print("周三走了", daily_steps[2], "步")
# 计算一周总步数
total_steps = sum(daily_steps)
print("一周总步数:", total_steps)原始步数: [5000, 6000, 7000, 5500, 8000, 3000, 4000]
修改后步数: [5000, 6000, 8000, 5500, 8000, 3000, 4000]
周三走了 8000 步
一周总步数: 39500看到列表的方便了吗?想改哪个数据,直接通过索引找到它,然后赋值就行!
本章小结
今天我们完成了一个重要的升级:用列表替换元组。虽然只是换了个容器,但带来的编程思路变化是巨大的:
📋 行动清单
- 运行今天的完整代码,输入几个不同的日期,验证计算结果
- 尝试修改代码:如果把列表改回元组,程序还能运行吗?试试看!
- 思考一个场景:在你的生活或工作中,有哪些数据适合用列表存储?哪些适合用元组?
关键收获:
- 列表是可变的,创建后可以修改其中的元素
- 元组是不可变的,创建后就不能改了
- 列表适合存储同类型、需要修改的数据序列
- 元组适合存储不同类型、固定不变的数据结构
- 把独立功能写成函数(如
is_leap_year),能让代码更清晰、更易维护
列表的「可变性」就像给你的数据装上了「可调节旋钮」——需要的时候随时调整。而元组的「不可变性」则像给你的数据加了「保护锁」——确保它不会被意外修改。
下一节,我们要认识第三种容器:集合。它和数学里的集合概念很像,能帮我们解决一些列表和元组不太擅长的问题。比如:如何快速找出两个名单中重复的名字?集合有妙招!
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第6章代码包:判断第几天(含全部版本 4 个 .py)ZIP · 3KB