得到(年,月)最后X个月

the*_*ega 7 python datetime

我在python中有一个非常简单的事情:我需要(year,month)从今天开始(包括)最后x个月的元组列表.因此,对于x = 10和今天(2011年7月),命令应该输出:

[(2011, 7), (2011, 6), (2011, 5), (2011, 4), (2011, 3), 
(2011, 2), (2011, 1), (2010, 12), (2010, 11), (2010, 10)]
Run Code Online (Sandbox Code Playgroud)

只应使用python的默认日期时间实现.我提出了以下解决方案:

import datetime
[(d.year, d.month) for d in [datetime.date.today()-datetime.timedelta(weeks=4*i) for i in range(0,10)]]
Run Code Online (Sandbox Code Playgroud)

这个解决方案为我的测试用例输出了正确的解决方案,但我对这个解决方案不满意:假设一个月有四个星期,这根本不是真的.我可以取代weeks=4days=30这将使一个更好的解决方案,但它仍然是不正确的.

我想到的另一个解决方案是使用简单的数学并从月份计数器中减去1,如果月份计数器为0,则从年份计数器中减去1.这个解决方案的问题是:它需要更多的代码,也不是很易读.

那怎么能正确完成呢?

slo*_*dog 20

我没有看到它记录在任何地方,但是time.mktime当给定超出范围(包括负月值)时,它将"翻转"到正确的年份:

x = 10
now = time.localtime()
print([time.localtime(time.mktime((now.tm_year, now.tm_mon - n, 1, 0, 0, 0, 0, 0, 0)))[:2] for n in range(x)])
Run Code Online (Sandbox Code Playgroud)


tri*_*het 7

使用relativedelta...

import datetime
from dateutil.relativedelta import relativedelta

def get_last_months(start_date, months):
    for i in range(months):
        yield (start_date.year,start_date.month)
        start_date += relativedelta(months = -1)

>>> X = 10       
>>> [i for i in get_last_months(datetime.datetime.today(), X)]
>>> [(2013, 2), (2013, 1), (2012, 12), (2012, 11), (2012, 10), (2012, 9), (2012, 8), (2012, 7), (2012, 6), (2012, 5)]
Run Code Online (Sandbox Code Playgroud)


cwb*_*cwb 6

Neatest将使用整数除法//)和模数%)函数,用自0年以来的月数表示月份:

months = year * 12 + month - 1 # Months since year 0 minus 1
tuples = [((months - i) // 12, (months - i) % 12 + 1) for i in range(10)]
Run Code Online (Sandbox Code Playgroud)

当我们在稍后将模数函数的结果加1以获得1索引时(即月份从1到12而不是0到11)- 1months表达式中的in 是获得正确答案的要求。

或者您可能想创建一个生成器:

def year_month_tuples(year, month):
    months = year * 12 + month - 1 # -1 to reflect 1-indexing
    while True:
        yield (months // 12, months % 12 + 1) # +1 to reflect 1-indexing
        months -= 1 # next time we want the previous month
Run Code Online (Sandbox Code Playgroud)

可以用作:

>>> tuples = year_month_tuples(2011, 7)
>>> [tuples.next() for i in range(10)]
Run Code Online (Sandbox Code Playgroud)