判断第几天/判断第几天(2)

去社区提问

简介:用列表替代元组,实现‘判断第几天’的功能。

案例描述

欢迎继续学习小象学院Python认知打卡课~

上节课中,我们实现了用户从键盘输入的日期,自动判断这个日期是一年中的第几天的功能。

在讲解过程中,我们把12个月的天数存放在了容器元组中,元组有一个特点是一旦创建,内容就无法改变。

上节课的末尾给大家留了一个小小的思考题:如果改用列表存放每月的天数,程序应该怎么写呢?

本节课就和我一起来探索答案,我们会把程序改变得更加优雅~

案例分析

先来简单回顾一下上节课的思路:

计算天数时,我们的策略是:

日期转换后的年份、月份、日期分别存储在变量yearmonthday中;

将一年12个月的天数放在元组中,利用元组统计month-1个月天数总和,再加当月日期day

当输入的年份是闰年,且用户输入日期的月份数大于2时,求和的天数结果+1。

上节课的思路用代码来实现。

  1. # 判断第一天1.0
  2. import datetime
  3. input_date_str = input('请输入日期(yyyy/mm/dd):')
  4. input_date = datetime.datetime.strptime(input_date_str, '%Y/%m/%d')
  5. print(input_date)
  6. year = input_date.year
  7. month = input_date.month
  8. day = input_date.day
  9. # 计算之前月份天数的总和以及当前月份天数
  10. days_in_month_tup = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
  11. days = sum(days_in_month_tup[: month - 1]) + day
  12. # 判断闰年
  13. if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
  14. if month > 2:
  15. days += 1
  16. print('这是第{}天。'.format(days))

现在这段代码看起来还是有些繁杂,我们先想个办法给程序变个身,让它有更好的可读性。

可以把判断闰年的功能用函数封装起来,然后在主程序直接调用它来使用。关于函数的定义和使用之前的课程已经多次讲到,下面请你直接来读这段代码。

  1. def is_leap_year(year):
  2. # 判断year是否闰年,是,返回True;否,返回False
  3. if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
  4. return True
  5. else:
  6. return False

函数is_leap_year的参数是年份year,函数功能是判断当前年份是否为闰年。如果是,则返回值是True,否则返回False

上面的代码中,我们利用if条件分支和两个return语句完成了不同条件下返回不同值的功能。但通常情况下,我们不会为函数设置两个return语句,那么如何修改代码,只用一个return语句实现相同的功能呢?

暂时没想到好主意也没关系,也许你能从下面这个例子中得到启发:

今年过年妈妈给胖虎准备了一个红包,往红包里放了1000块钱。

如果胖虎期末考试考到了前三名,就往红包中再加1000块钱。

大年初一的时候把准备好的红包送给可爱的胖虎同学。

妈妈给胖虎的红包就相当于函数的返回值,不论胖虎期末考试进入前三名还是没有进入前三名,妈妈给胖虎的都是这一个红包。只不过先给红包的金额设定了一个默认值,万一考试成绩超出预期,再继续改变金额数值。

根据这个思路,我们可以来改写函数。

设置一个变量is_leap,给它定义初始值为False,如果判断年份满足闰年条件,就改变is_leap的值为True,否则还维持它的值不变。最后返回is_leap

  1. def is_leap_year(year):
  2. # 判断year是否闰年,是,返回True;否,返回False
  3. is_leap = False
  4. if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
  5. is_leap = True
  6. return is_leap

写好了函数,在主程序中就可以调用它啦~

  1. # 判断第一天1.0
  2. import datetime
  3. def is_leap_year(year):
  4. # 判断year是否闰年,是,返回True;否,返回False
  5. is_leap = False
  6. if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
  7. is_leap = True
  8. return is_leap
  9. input_date_str = input('请输入日期(yyyy/mm/dd):')
  10. input_date = datetime.datetime.strptime(input_date_str, '%Y/%m/%d')
  11. print(input_date)
  12. year = input_date.year
  13. month = input_date.month
  14. day = input_date.day
  15. # 计算之前月份天数的总和以及当前月份天数
  16. days_in_month_tup = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
  17. days = sum(days_in_month_tup[: month - 1]) + day
  18. # 判断闰年
  19. if is_leap_year(year) & month>2:
  20. days += 1
  21. print('这是第{}天。'.format(days))

函数is_leap_year返回True,年份是闰年,并且月份month>2,总天数+1。

下面我们来研究如何把盛放天数的容器从元组更换为列表。

作为容器来说,列表和元组的功能基本相同。只不过要再唠叨一次,元组创建后不能改变内容,而列表可以修改内容。

之前在元组中,设置二月天数28:days_in_month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

由于现在改用列表存储,当判断年份为闰年时,可以利用它与元组的不同特点,修改2月的天数为29。

这样一来也可以省去判断用户输入,月份是否大于2的操作,直接用列表中的天数信息进行加和就可以了~

按照上面的思路来改写代码:

  1. from datetime import datetime
  2. def is_leap_year(year):
  3. # 判断year是否闰年,是,返回True;否,返回False
  4. is_leap = False
  5. if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
  6. is_leap = True
  7. return is_leap
  8. input_date_str = input('请输入日期(yyyy/mm/dd):')
  9. input_date = datetime.strptime(input_date_str, '%Y/%m/%d')
  10. year = input_date.year
  11. month = input_date.month
  12. day = input_date.day
  13. # 计算之前月份天数的总和以及当前月份天数
  14. days_in_month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  15. if is_leap_year(year):
  16. days_in_month_list[1] = 29
  17. days = sum(days_in_month_list[: month - 1]) + day
  18. print('这是{}年的第{}天。'.format(year, days))

可以看到,在代码中,定义了列表days_in_month_list存储12个月的天数信息,当判定年份是闰年时,改变列表中二月的天数为29。由于二月是列表中的第二个元素,索引值从0开始,用这行代码来完成列表中内容的修改:

  1. days_in_month_list[1] = 29

最后来运行代码看看结果:

本关总结

本节课主要带领大家复习了函数以及列表元组的用法。

  • 列表和元组

列表list:使用方括号[]创建

元组tuple:使用圆括号()创建

元组是不可变的,列表是可变的

元组和列表中的元素都是有序的,可以通过索引值获取元素。

下节预告

下节课我们将学习Python中一个新的数据结构:集合。能够按不同天数将月份划分为不同集合,然后再操作。

想要获取课程资料,和更多同学一起交流学习,欢迎添加班主任微信~我们下节课不见不散。

扫描二维码添加班主任微信

已经添加过班主任的同学无需重复扫码,直接联系对应老师即可。

判断第几天 1/3

判断第几天(2)

1.0x

恭喜完成本课时的学习!
坚持学习

行动力超过

累计学习

学习下一课时