我想创建一个python函数,允许我迭代从起点到停止点的几个月.例如,它看起来像
def months(start_month, start_year, end_month, end_year):
Run Code Online (Sandbox Code Playgroud)
呼叫months(8, 2010, 3, 2011)将返回:
((8, 2010), (9, 2010), (10, 2010), (11, 2010), (12, 2010), (1, 2011), (2, 2011), (3, 2011))
Run Code Online (Sandbox Code Playgroud)
该函数可以返回一个元组元组,但我希望将其视为生成器(即使用yield).
我检查了calendarpython模块,它似乎没有提供此功能.我可以写一个令人讨厌的for循环来轻松地完成它,但我很想知道专业人员可以做得多么优雅.
谢谢.
S.L*_*ott 43
日历的工作方式如下.
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
Run Code Online (Sandbox Code Playgroud)
所有多单元的东西都是这样的.英尺和英寸,小时,分钟和秒等等.唯一不那么简单的事情是数月或数月 - 因为月份是不规则的.其他一切都是常规的,你需要在最细粒度的单位工作.
eto*_*ipi 10
由于其他人已经提供了生成器的代码,我想补充一下 Pandas 有一个名为“ period_range ”的方法,在这种情况下,它可以接收开始和结束、年和月,并返回一个周期索引,适合迭代。
import pandas as pd
pr = pd.period_range(start='2010-08',end='2011-03', freq='M')
prTupes=tuple([(period.month,period.year) for period in pr])
#This returns: ((8, 2010), (9, 2010), (10, 2010), (11, 2010), (12, 2010), (1, 2011), (2, 2011), (3, 2011))
Run Code Online (Sandbox Code Playgroud)
months使用dateutil模块功能
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)]
Run Code Online (Sandbox Code Playgroud)
用法示例
print months(11, 2010, 2, 2011)
#[(11, 2010), (12, 2010), (1, 2011), (2, 2011)]
Run Code Online (Sandbox Code Playgroud)
或以迭代器形式
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))
Run Code Online (Sandbox Code Playgroud)
迭代器用法
for m in month_iter(11, 2010, 2, 2011):
print m
#(11, 2010)
#(12, 2010)
#(1, 2011)
#(2, 2011)
Run Code Online (Sandbox Code Playgroud)
也许这种优雅或速度可以提高,但这是直截了当的解决方案:
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
Run Code Online (Sandbox Code Playgroud)
编辑:这是一个不太直接的,甚至可以避免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))
Run Code Online (Sandbox Code Playgroud)