Python:让所有月份都在范围内?

新手上路,请多包涵

我想要从现在到 2010 年 8 月之间的所有月份,作为格式如下的列表:

 ['2010-08-01', '2010-09-01', .... , '2016-02-01']

现在这就是我所拥有的:

 months = []
for y in range(2010, 2016):
    for m in range(1, 13):
        if (y == 2010) and m < 8:
            continue
        if (y == 2016) and m > 2:
            continue
        month = '%s-%s-01' % (y, ('0%s' % (m)) if m < 10 else m)
        months.append(month)

什么是更好的方法来做到这一点?

原文由 Richard 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 336
2 个回答

dateutil.relativedelta 在这里很方便。

我把格式化作为练习留了下来。

 from dateutil.relativedelta import relativedelta
import datetime

result = []

today = datetime.date.today()
current = datetime.date(2010, 8, 1)

while current <= today:
    result.append(current)
    current += relativedelta(months=1)

原文由 Ani 发布,翻译遵循 CC BY-SA 3.0 许可协议

我查看了 dateutil 文档。事实证明,它提供了一种比使用 dateutil.relativedelta 更方便的方法: 重复规则示例

对于手头的任务,它就像

from dateutil.rrule import *
from datetime import date

months = map(
    date.isoformat,
    rrule(MONTHLY, dtstart=date(2010, 8, 1), until=date.today())
)

细则

请注意,我们在这里作弊了一点。 The elements dateutil.rrule.rrule produces are of type datetime.datetime , even if we pass dtstart and until of type datetime.date ,正如我们上面所做的。我让 map 将它们提供给 dateisoformat 函数,结果只是将它们转换为字符串,就好像它是-天信息。

因此,看似等价的列表理解

[day.isoformat()
    for day in rrule(MONTHLY, dtstart=date(2010, 8, 1), until=date.today())]

会返回一个列表

['2010-08-01T00:00:00',
 '2010-09-01T00:00:00',
 '2010-10-01T00:00:00',
 '2010-11-01T00:00:00',
 ⋮
 '2015-12-01T00:00:00',
 '2016-01-01T00:00:00',
 '2016-02-01T00:00:00']

因此,如果我们想使用列表理解而不是 map ,我们必须做类似的事情

[dt.date().isoformat()
    for dt in rrule(MONTHLY, dtstart=date(2010, 8, 1), until=date.today())]

原文由 das-g 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题