python输出间隔_生成python中间隔之间的月份列表

>>> from datetime import datetime, timedelta

>>> from collections import OrderedDict

>>> dates = ["2014-10-10", "2016-01-07"]

>>> start, end = [datetime.strptime(_, "%Y-%m-%d") for _ in dates]

>>> OrderedDict(((start + timedelta(_)).strftime(r"%b-%y"), None) for _ in xrange((end - start).days)).keys()

['Oct-14', 'Nov-14', 'Dec-14', 'Jan-15', 'Feb-15', 'Mar-15', 'Apr-15', 'May-15', 'Jun-15', 'Jul-15', 'Aug-15', 'Sep-15', 'Oct-15', 'Nov-15', 'Dec-15', 'Jan-16']

更新:根据一条评论中的要求进行一些解释.这里有三个问题:将日期解析为适当的数据结构(strptime);给出两个极端和步骤(一个月)的日期范围;格式化输出日期(strftime). datetime类型重载了减法运算符,因此end-start是有意义的.结果是timedelta对象表示两个日期之间的差异,而.days属性获得以天为单位表示的差异.没有.months属性,因此我们一次迭代一天并将日期转换为所需的输出格式.这会产生大量重复,OrderedDict会在保持项目顺序正确的情况下删除它们.

现在这简单而简洁,因为它让datetime模块完成所有工作,但它也非常低效.我们每天都会调用很多方法,而我们只需要输出几个月.如果性能不是问题,上面的代码就可以了.否则,我们将不得不更多地工作.让我们将上述实现与更有效的实现进行比较:

from datetime import datetime, timedelta

from collections import OrderedDict

dates = ["2014-10-10", "2016-01-07"]

def monthlist_short(dates):

start, end = [datetime.strptime(_, "%Y-%m-%d") for _ in dates]

return OrderedDict(((start + timedelta(_)).strftime(r"%b-%y"), None) for _ in xrange((end - start).days)).keys()

def monthlist_fast(dates):

start, end = [datetime.strptime(_, "%Y-%m-%d") for _ in dates]

total_months = lambda dt: dt.month + 12 * dt.year

mlist = []

for tot_m in xrange(total_months(start)-1, total_months(end)):

y, m = divmod(tot_m, 12)

mlist.append(datetime(y, m+1, 1).strftime("%b-%y"))

return mlist

assert monthlist_fast(dates) == monthlist_short(dates)

if __name__ == "__main__":

from timeit import Timer

for func in "monthlist_short", "monthlist_fast":

print func, Timer("%s(dates)" % func, "from __main__ import dates, %s" % func).timeit(1000)

在我的笔记本电脑上,我得到以下输出:

monthlist_short 2.3209939003

monthlist_fast 0.0774540901184

简洁的实现速度大约慢30倍,因此我不建议在时间要求严格的应用程序中使用:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值