Python中输入起止日期,如:input = [20200120,20200519]
如何输出期间所有的文本?如下图:
image.png

思考五秒钟~
5
4
3
2
1

我们看代码

from datetime import datetime, timedelta

def create_date_range(inp):
    result_list = []
    sta_day = datetime.strptime(str(inp[0]), '%Y%m%d')
    end_day = datetime.strptime(str(inp[1]), '%Y%m%d')
    dlt_day = (end_day - sta_day).days + 1

    for i in range(dlt_day):
        tmp_day = sta_day + timedelta(days=i)
        tmp_day_txt = tmp_day.strftime('%Y%m%d')
        result_list.append(tmp_day_txt)

    return result_list

input = [20200120,20200519]
print(create_date_range(input))

我们看思路

把输入的起止日期数字输出为文本,分三步:

  1. 建立一个空列表;
  2. 算出答案,放进这个空列表;
  3. 输出该列表。

但这怎么好像在回答如何把大象装进冰箱时回答说,分三步:

  1. 打开冰箱门;
  2. 把大象放进去;
  3. 关上冰箱门。

等于没说,关键在于如何执行第二步。

> 这个问题的本质很简单:从起始日开始,逐一写下日期,直到终止日。

遇到“逐一”,就应该想到循环。

循环的起点起始日是 input[0]
循环的终点终止日是 input[1]
循环的次数是:两日期的间隔天数 = 终止日期 - 起始日期 + 1

但是我们并不能直接把起点日期和终点日期直接相减,因为它们还不是日期,而是数字。20200519-20200120的结果是399,而实际两天的间隔是120天,对新手而言,跨月多烦心,不过别担心,datetime模块让你隔月若比邻。

from datetime import datetime, timedelta

导入datetime模块的同时,导入timedelta,用来计算时间间隔。

Python里写个函数非常简单,直接def就行了:
def create_date_range(inp):

def是定义函数的关键字,相当于哈利波特的咒语,能直接从你的电脑机箱里召唤出会飞的扫帚,create_date_range是函数名,相当与扫帚名,好东西总得有个名字,否则没法使唤,用下划线分开是为了一眼就能认出它们,降低我们的识别成本,毕竟人写的代码除了喂给机器吃之外,最终还是要端给人看的。

函数是输入和输出之间的桥梁,在这里,输入是inp,输出是什么?是result_list,所以要用:

return result_list

代表输出结果。

为了计算输出结果result_list,我们必须在函数最初设置一个空列表:result_list = []

那么凭什么知道函数已经结束?缩进告诉你,于是我们有了这样的架构:

def create_date_range(inp):
    result_list = []

    return result_list

当你看到def以下的语句不再缩进,那么def定义的函数也就结束了。如果你是Python初学者,请你仔细端详这个架构,这几乎是Python生命力的全部。


终于到了把大象塞进冰箱的环节,也就是要逐一写下日期的步骤,分两步:

第一步,计算首尾日期间隔天数,用于确定从起始日期开始输出的循环次数;间隔天数 = 终止日期-起始日期+1

我们必须把起始日期和终止日期都转换成日期,然后才能相减,于是我们先计算起始日期:

sta_day = datetime.strptime(str(inp[0]), '%Y%m%d')

在我们的函数里,输入是inp,inp[0]代表列表的第一个元素,即20200120

你可能会问,我们的输入不是input么,为什么会变成inp?对,但是inp有别于input,input是函数外的事情,函数内部只认inp。inp是函数的参数,这个参数接收外部输入,在函数内部进行处理。至于外部输入是input还是output,对于函数本身来说并不重要,函数内的一切都通过参数inp传递。

str()也是一个函数,小巧玲珑,可以把像数字那样的对象转换成文本:
image.png

如果你偏要问为什么要把好端端的数字转换成文本,那么就要怪datetime的特性:它只会把文本转换为日期,毕竟只有换算成日期,才能计算日期间隔。实现方式是通过datetime.strptime

sta_day = datetime.strptime(str(inp[0]), '%Y%m%d')

在这里,'%Y%m%d'是告诉datetime要把什么样的文本转换成日期,'%Y%m%d'代表即将要转换的日期格式是yyyymmdd的格式,也就是要把文本'20200120'转换成日期格式。

同样的道理,下面计算终止日期:

end_day = datetime.strptime(str(inp[1]), '%Y%m%d')

那么,逐一重复的次数,也就是循环步长dlt_day就很简单:

dlt_day = (end_day - sta_day).days + 1

你只需要记住.days在这里计算datetime格式的天数,end_day和sta_day两个datetime类型字段相减,.days算出间隔天数,+1算出要循环步长,简洁优雅,Simple but elegant.

第二步,循环。

和函数一样,Python的循环只有一行代码,像这样:

 for i in range(dlt_day):

for和def一样,是关键字,告诉Python我要开始重复劳动了,重复多少次呢?上面这条语句告诉你,从0开始逐一重复到dlt_day结束,简洁优雅,Simple but elegant.

具体重复那些劳动?缩进告诉你,当你看到for下面的语句不再缩进时,循环也就结束了。

这里的循环分三步:

第一步,计算逐一要写的日期tmp_day,可以理解为临时日期,写完放一边,不必去挂念。

tmp_day = sta_day + timedelta(days=i)

通过起始日期 + 间隔天数的方式实现,第一次循环标识i=0,即起始日期+0天(2020年1月20日),第二次i=1,即起始日期+1天(2020年1月21日)……最终写到2020年5月19日。

第二步,把日期转换成文本,这样才能打印出来看。实现方式是通过datetime中的strftime方法

tmp_day_txt = tmp_day.strftime('%Y%m%d')

同样,这里的'%Y%m%d'是告诉datetime的strftime方法要转换成什么样的字符,参考上文,'%Y%m%d'表示“20200120”这样的格式。

第三步,通过.append方法记下临时日期tmp_day,通过一次次循环,一个个累在result_list中,最终梭哈一把输出结果。

实操代码及运行结果

image.png


汤强
1 声望0 粉丝

练钢琴的秘诀很简单,把乐谱拆成音符,刻意练习后,手感就能连接音符。练编程的秘诀同样简单:切碎代码,敲出来、跑起来、把bug抖出来,重复10遍,重复10天,当你大脑里的神经网络连成片时,就能和练钢琴一样,让...