如何创建一个月

2024-06-08 14:36:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个python函数,它允许我在几个月内从一个起点到一个终点进行迭代。例如,它看起来像

def months(start_month, start_year, end_month, end_year):

调用months(8, 2010, 3, 2011)将返回:

((8, 2010), (9, 2010), (10, 2010), (11, 2010), (12, 2010), (1, 2011), (2, 2011), (3, 2011))

这个函数可以返回一个元组的元组,但我希望它是一个生成器(即使用yield)。

我已经检查了calendarpython模块,它似乎没有提供此功能。我可以写一个讨厌的for循环来轻松地完成它,但是我很感兴趣的是看一个专业人士能做得多么优雅。

谢谢。


Tags: 模块函数功能fordefyearstartend
3条回答

使用dateutil模块的months函数

from dateutil.rrule import rrule, MONTHLY
from datetime import datetime

def months(start_month, start_year, end_month, end_year):
    start = datetime(start_year, start_month, 1)
    end = datetime(end_year, end_month, 1)
    return [(d.month, d.year) for d in rrule(MONTHLY, dtstart=start, until=end)]

示例用法

print months(11, 2010, 2, 2011)
#[(11, 2010), (12, 2010), (1, 2011), (2, 2011)]

或迭代器形式

def month_iter(start_month, start_year, end_month, end_year):
    start = datetime(start_year, start_month, 1)
    end = datetime(end_year, end_month, 1)

    return ((d.month, d.year) for d in rrule(MONTHLY, dtstart=start, until=end))

迭代器用法

for m in month_iter(11, 2010, 2, 2011):
    print m
    #(11, 2010)
    #(12, 2010)
    #(1, 2011)
    #(2, 2011)

日历是这样工作的。

def month_year_iter( start_month, start_year, end_month, end_year ):
    ym_start= 12*start_year + start_month - 1
    ym_end= 12*end_year + end_month - 1
    for ym in range( ym_start, ym_end ):
        y, m = divmod( ym, 12 )
        yield y, m+1

所有多个单位的东西都是这样工作的。英尺和英寸、小时、分钟和秒等等。唯一不能这么简单的是几个月、几天或几个月、几周,因为几个月是不规则的。其他的一切都是规则的,您需要在细粒度的单元中工作。

或许这一过程的优雅或速度可以得到提高,但这是一个直截了当的解决方案:

def months(start_month, start_year, end_month, end_year):
    month, year = start_month, start_year
    while True:
        yield month, year
        if (month, year) == (end_month, end_year):
            return
        month += 1
        if (month > 12):
            month = 1
            year += 1

编辑:这里有一个更简单的方法,它甚至可以通过使用生成器理解来避免使用yield

def months2(start_month, start_year, end_month, end_year):
    return (((m_y % 12) + 1, m_y / 12) for m_y in
            range(12 * start_year + start_month - 1, 12 * end_year + end_month))

相关问题 更多 >