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

去社区提问

简介:‘判断第几天‘3.0版本,将月份划分为不同的集合再操作。

案例描述

欢迎来到今天的课堂~

之前的两节课中,存放12个月的天数信息我们分别使用了元组和列表这两种容器,也了解了它们的异同点。

3.0版本,我将为你介绍Python中另一个数据结构:集合。

将月份划分为不同的集合再进行计算操作。

案例分析

首先我们来一起了解一下集合

集合的特点

Python中集合(set)类型和数学中集合的概念一致,即包含0或多个数据项的无序组合。

来回忆一下,创建列表时,我们使用的是方括号[],创建元组使用圆括号(),今天介绍的集合要使用花括号{}创建。

例如定义一个形状的集合s:

代码练习:

编程区

  1. s = {'三角形','正方形','圆形'}
  2. print(s)

终端区

知道了创建集合的方式,下面再来看看它有哪些特点:

  • 互异性

集合中的元素不可以重复,就是集合中不会出现两个相同的元素。

先创建一个列表,列表中存入我们喜欢的零食:

代码练习:

编程区

  1. l = ['旺旺雪饼','果冻','QQ糖','浪味仙']
  2. print(l)

终端区

现在想往零食列表中再增加一袋QQ糖,使用append()方法,可以向列表中增加元素:

代码练习:

编程区

  1. l.append('QQ糖')
  2. print(l

终端区

现在列表的最后就又加入了一个新的元素QQ糖。如果我们把同样的零食存储在集合中,会怎样呢?

代码练习:

编程区

  1. s = {'旺旺雪饼','果冻','QQ糖','浪味仙','QQ糖'}
  2. print(s)

终端区

奇怪的事情发生了,在定义集合的时候明明放进去了两个QQ糖,但打印的时候却只保留了一个。

我们刚才讲过,集合中的元素不可以重复,所以创建集合时,相同的元素会自动被删除,只保留一个在集合中。因此集合也常常被用来完成元素去重的任务。

  • 无序性

集合的另一个特点是它具有无序性。集合是无序的组合,因此没有索引和位置的概念。

我们无法通过索引的方式像列表和元组一样取出集合中的元素。

集合的操作

接下来我们来说说集合的一些常见操作。

1.s-ts.difference(t) 返回在集合s中但不在t中的元素

用一个例子来感受一下:

代码练习:

编程区

  1. s = {1,3,5,7}
  2. t = {3,5}
  3. print(s-t)

终端区

2.s&ts.intersection(t) 返回同时在集合s和t中的元素

代码练习:

编程区

  1. s = {1,3,5,7}
  2. t = {1,3,4,6}
  3. print(s&t)

终端区

3.s|ts.union(t) 返回集合s和t中的所有元素

代码练习:

编程区

  1. s = {1,3}
  2. t = {5,7}
  3. print(s|t)

终端区

4.s^ts.symmetric_difference(t) 返回集合s和t中的元素,但不包括同时在其中的元素

代码练习:

编程区

  1. s = {1,2,3,4,5}
  2. t = {1,3,5}
  3. print(s^t)

终端区

关于集合的基本操作就介绍到这里~接下来我们就利用集合来划分月份,完成天数计算。

集合中不能有重复的元素,而每月的天数只有30、31、28(或29)这几个选择,一定会存在重复现象。因此我们就不能像使用列表和元组那样把每个月的天数存放在同一个集合中。

就只能寻找其他方案了。

逆向思考一下,之前我们都是把每月的天数放进容器,那可不可以试着把月份放入代表不同天数的容器中呢?

我们可以创建两个集合,把1-12(除了2月)这11个月分为:当月天数30和当月天数31这两类。

  1. # 包含30天 月份集合
  2. _30_days_month_set = {4,6,9,11}
  3. # 包含31天 月份集合
  4. _31_days_month_set = {1,3,5,7,8,10,12}

这里有一个地方需要注意,变量不能以数字开头,为避免程序报错,我们在前面加了一个下划线。

计算天数的大致思路是这样的,假如用户输入2021/05/20,先计算1-4月的天数总和,再加上5月的20天。

这样当我们计算时,首先判断月份属于哪个集合:

如果属于_30_days_month_set,总天数加30;

如果属于_31_days_month_set,总天数加31;

如果月份的数字都不在这两个集合中,说明是2月,先给总天数加28,后续再判断是否闰年。

主程序中依然先把输入的时间日期转换为标准格式:

  1. from datetime import datetime
  2. input_date_str = input('请输入日期(yyyy/mm/dd):')
  3. input_date = datetime.strptime(input_date_str, '%Y/%m/%d')
  4. year = input_date.year
  5. month = input_date.month
  6. day = input_date.day

最终的计算结果用变量days存储,初始0。我们先把年/月/日里面的日期day加上。例如2021/05/20,先把五月的20天加和到结果中。

  1. days = 0
  2. days += day

下面就需要利用循环把1到month-1月的天数相加。我们选用for循环来实现这个效果。

  1. for i in range(1,month):

i在循环中将分别等于1到month-1的每个数字。循环体中需要判断数字i属于哪个集合,用符号in就可以实现这个功能:

  1. for i in range(1,month):
  2. if i in _30_days_month_set:
  3. days += 30
  4. elif i in _31_days_month_set:
  5. days += 31
  6. else:
  7. days += 28

当年份是闰年且month>2的条件下,总天数days+1,判断闰年调用定义好的函数is_leap_year:

  1. # 定义函数
  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
  1. if is_leap_year(year) and month > 2:
  2. days += 1

整体来看一下本节课的代码:

  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. # 包含30天 月份集合
  14. _30_days_month_set = {4, 6, 9, 11}
  15. # 包含31天 月份集合
  16. _31_days_month_set = {1, 3, 5, 7, 8, 10, 12}
  17. # 初始化值
  18. days = 0
  19. days += day
  20. for i in range(1, month):
  21. if i in _30_days_month_set:
  22. days += 30
  23. elif i in _31_days_month_set:
  24. days += 31
  25. else:
  26. days += 28
  27. if is_leap_year(year) and month > 2:
  28. days += 1
  29. print('这是{}年的第{}天。'.format(year, days))

运行来看看效果吧~

本关总结

本节课的内容就到这里啦,下面来一起梳理一下重点知识~

  • 集合

集合的特点:

互异性,集合中不能出现重复的元素

无序性,集合中的元素是没有顺序的

集合的操作:

下节预告

能否将月份和天数信息同时表示在一种数据类型中,让他们显示对应关系?

下节课我将为你介绍Python的另一种数据结构:字典。

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

扫描二维码添加班主任

判断第几天 1/3

判断第几天(3)

1.0x

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

行动力超过

累计学习

学习下一课时