查看全课大纲(第 29 / 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.空气质量数据怎么“洗”干净,还能画成图?
把月份和天数“锁”在一起:用字典给数据配个对
约 17 分钟
小象实战讲义 · Python 入门:8 个小项目边玩边学
前面几节课,我们像整理衣柜一样,把月份按天数分成了不同的“抽屉”(集合)。今天,我们要玩个更酷的:直接把“月份”和“天数”配成一对,像钥匙和锁一样,把它们“锁”在一起。这样,想查任何一个月有多少天,直接问“钥匙”就行了。实现这个神奇功能的数据类型,就是 Python 里的字典(Dictionary)。学完这一节,你的“判断第几天”程序会变得更清晰、更强大。
💡 核心导读
- 新武器:字典:一种“键-值”配对的数据结构,像查字典一样,用“键”就能找到对应的“值”。
- 项目升级:用字典来存储“月份-天数”的对应关系,让数据组织一目了然。
- 字典的基本操作:创建、添加、访问、修改和删除字典里的数据。
- 字典的遍历:如何查看字典里所有的“钥匙”和“宝藏”。
从“分开放”到“锁一起”:字典登场
在之前的版本里,我们把30天的月份放在一个集合 {4, 6, 9, 11},31天的月份放在另一个集合 {1, 3, 5, 7, 8, 10, 12}。这很好,但有没有一种方法,能让我们一眼就看到“1月对应31天,2月对应28天……”呢?
当然有!Python 的字典(dict) 就是干这个的。它把数据组织成一个个“键值对”(Key-Value Pair)。你可以把“键”想象成一把独一无二的钥匙,“值”就是这把钥匙能打开的宝箱里的东西。
生活中的字典例子:
- 身份证号(键) 对应 个人信息(值)。
- 商品名称(键) 对应 商品价格(值)。
字典的查找方式叫映射:你拿着“键”这把钥匙,就能直接找到它映射的那个“值”,速度非常快。我们使用字典时通常也不关心数据的排列先后,只关心“键”和“值”的配对关系。(补充:自 Python 3.7 起,字典会保留键值对插入时的顺序,但这不是我们使用字典时依赖的特性;真正“无序”的是下一章会遇到的集合 set。)
玩转字典:创建、增删改查
让我们在代码里亲手创建一个字典,感受一下它的魔力。
# 1. 创建一个空字典
price_dict = {} # 或者 price_dict = dict()
print("空字典:", price_dict)
# 2. 向字典中添加数据(键值对)
price_dict['鸡蛋'] = 2.59 # 键是'鸡蛋',值是2.59
price_dict['牛奶'] = 3.19
price_dict['奶酪'] = 4.80
print("添加商品后:", price_dict)
# 3. 访问字典中的值(通过键)
milk_price = price_dict['牛奶']
print("牛奶的价格是:", milk_price)
# 4. 修改字典中的值
price_dict['鸡蛋'] = 3.59 # 鸡蛋涨价了
print("鸡蛋涨价后:", price_dict)
# 5. 删除字典中的项
del price_dict['奶酪']
print("删除奶酪后:", price_dict)
# 6. 检查某个键是否在字典中
print("'鸡蛋'在字典中吗?", '鸡蛋' in price_dict)
print("'酸奶'在字典中吗?", '酸奶' in price_dict)空字典: {}
添加商品后: {'鸡蛋': 2.59, '牛奶': 3.19, '奶酪': 4.80}
牛奶的价格是: 3.19
鸡蛋涨价后: {'鸡蛋': 3.59, '牛奶': 3.19, '奶酪': 4.80}
删除奶酪后: {'鸡蛋': 3.59, '牛奶': 3.19}
'鸡蛋'在字典中吗? True
'酸奶'在字典中吗? False看,字典的操作非常直观!用方括号[]里面放上“键”,就能进行赋值(添加/修改)、访问和删除。
项目升级4.0:用字典重构“月份-天数”
现在,回到我们的核心项目。本节我们只新增一件事:用字典来存储每个月份对应的天数。 这会让我们的数据看起来就像一张清晰的表格。
思路很简单:
- 键(Key):月份(1, 2, 3, …)
- 值(Value):该月的天数(31, 28/29, 31, …)
我们来创建这个字典,并改写计算逻辑:
from datetime import datetime
def is_leap_year(year):
"""判断是否为闰年"""
return (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0))
# 假设输入日期为 2017/03/05 和 2012/03/05,用固定值代替input()
input_date_str_list = ['2017/03/05', '2012/03/05']
for input_date_str in input_date_str_list:
input_date = datetime.strptime(input_date_str, '%Y/%m/%d')
year = input_date.year
month = input_date.month
day = input_date.day
# 4.0 核心升级:创建月份-天数字典
month_days_dict = {
1: 31, # 1月有31天
2: 28, # 先按平年算,2月28天
3: 31,
4: 30,
5: 31,
6: 30,
7: 31,
8: 31,
9: 30,
10: 31,
11: 30,
12: 31
}
# 现在,想知道某个月有多少天,直接 month_days_dict[月份] 就行了!
# 计算总天数
total_days = day # 先加上当月的天数
# 累加之前月份的天数
for m in range(1, month): # 从1月累加到(month-1)月
total_days += month_days_dict[m]
# 如果是闰年且月份大于2月,需要加1天
if is_leap_year(year) and month > 2:
total_days += 1
print(f'{input_date_str} 是{year}年的第{total_days}天。')2017/03/05 是2017年的第64天。
2012/03/05 是2012年的第65天。成功!代码变得更易读了。month_days_dict[3] 直接就是31,我们不再需要去判断3月属于哪个集合。
字典的遍历:看看里面都有啥
有时候我们想看看字典里所有的“钥匙”或者所有的“宝藏”,或者想一对一对地检查,该怎么做呢?字典提供了几种遍历方式:
# 沿用之前的商品价格字典
price_dict = {'鸡蛋': 3.59, '牛奶': 3.19, '面包': 5.50}
print("--- 遍历所有的键(商品名)---")
for key in price_dict.keys():
print(f"商品:{key}")
print("\n--- 遍历所有的值(价格)---")
for value in price_dict.values():
print(f"价格:{value}")
print("\n--- 遍历所有的键值对(数据项)---")
for key, value in price_dict.items(): # items()返回的是(键, 值)元组
print(f"{key} 的价格是 {value}")--- 遍历所有的键(商品名)---
商品:鸡蛋
商品:牛奶
商品:面包
--- 遍历所有的值(价格)---
价格:3.59
价格:3.19
价格:5.5
--- 遍历所有的键值对(数据项)---
鸡蛋 的价格是 3.59
牛奶 的价格是 3.19
面包 的价格是 5.5换个思路:用“天数”当键?
我们的 month_days_dict 是用月份作键,天数作值。讲师在视频里提了一个有趣的思考题:能不能反过来,用“天数”作键,“月份集合”作值呢?
当然可以!因为字典的“值”可以是任何类型,包括列表、集合等。
# 这是一个思考方向,不是最终代码
day_months_dict = {
30: {4, 6, 9, 11}, # 30天对应的月份集合
31: {1, 3, 5, 7, 8, 10, 12}, # 31天对应的月份集合
28: {2}, # 平年2月
29: {2} # 闰年2月
}如果这样组织数据,我们的计算逻辑可能就需要调整:先判断当前月份有多少天(需要查两次?),然后再去累加。这不一定比之前的方式更简单,但这是一个很好的思维训练,能帮你更深入地理解数据的多种组织方式。
📝 动手练一练
字典翻转:编写一段代码,将
price_dict = {'苹果': 5, '香蕉': 3, '橙子': 4}翻转成一个新字典,其中价格作为键,水果名作为值。注意,价格可能重复吗?如果重复该怎么处理?(提示:值可以用列表来存放多个水果名)探索官方“黑科技”:讲师提到,Python 标准库其实有一行代码就能算出一年中第几天的方法。请你根据提示(
strftime方法),查阅 Python 官方文档,找到这个格式化字符,并写一行代码验证它。(提示:关注%j这个格式符)
👉 点击查看第1题参考答案
思路:遍历原字典,对于每个键值对,以原“值”作为新字典的“键”,原“键”作为新字典的“值”。因为价格可能相同,所以新字典的值应该是一个列表,用来存放所有对应这个价格的水果。
price_dict = {'苹果': 5, '香蕉': 3, '橙子': 4, '梨': 3} # 香蕉和梨都是3元
flipped_dict = {}
for fruit, price in price_dict.items():
# 如果这个价格还没作为键出现过,就创建一个空列表
if price not in flipped_dict:
flipped_dict[price] = []
# 将水果名添加到这个价格对应的列表中
flipped_dict[price].append(fruit)
print(flipped_dict){5: ['苹果'], 3: ['香蕉', '梨'], 4: ['橙子']}👉 点击查看第2题参考答案
思路:datetime 对象有一个 strftime 方法,可以将日期格式化成字符串。查阅文档可知,%j 表示“一年中的第几天(001-366)”。我们可以直接用这个方法获取天数。
from datetime import datetime
# 假设日期是 2012/03/05
input_date = datetime.strptime('2012/03/05', '%Y/%m/%d')
day_of_year = input_date.strftime('%j') # %j 输出是字符串,如 '065'
print(f"2012/03/05 是这一年的第 {int(day_of_year)} 天。") # 转为整数2012/03/05 是这一年的第 65 天。看,一行 strftime(‘%j’) 就搞定了!我们之前写那么多代码,是为了学习元组、列表、集合、字典这些重要的基础知识。在实际工作中,如果发现标准库已有现成方案,直接用它往往是最高效、最可靠的选择。
本章小结
恭喜你!通过“判断第几天”这个项目,我们一口气解锁了 Python 中四种最常用的集合数据类型,它们就像编程世界里的四种“收纳容器”,各有各的妙用:
- 元组 (Tuple):
(1, 2, 3)—— 一旦创建,内容不可变,安全可靠,适合存放固定数据。 - 列表 (List):
[1, 2, 3]—— 灵活可变,有顺序,可以随时增删改查,最常用的“序列”。 - 集合 (Set):
{1, 2, 3}—— 元素不重复,且无序,擅长做成员检查、去重和集合运算(交、并、差)。 - 字典 (Dict):
{‘键’: ‘值’}—— “键-值”对的映射结构,通过唯一的“键”快速查找对应的“值”,组织关联数据的神器。
理解它们的区别(是否可变、是否有序、是否允许重复、如何索引),是你从“写代码”迈向“写好代码”的关键一步。
📋 行动清单
- 运行本节最后的完整项目代码,尝试输入不同的日期,看看结果是否正确。
- 动手完成“字典翻转”的练习,理解如何处理字典中值重复的情况。
- 访问 Python 官方文档,亲自查一下
strftime的用法,感受一下阅读一手资料的能力。
在下一个项目中,我们将面对一个新问题:程序运行完,结果就消失了,如何把它保存下来?我们将一起学习文件的基本操作,让你的程序学会“读写记忆”。同时,我们还会接触到循环的跳出技巧和令人期待的面向对象编程入门。敬请期待!
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第6章代码包:判断第几天(含全部版本 4 个 .py)ZIP · 3KB