You must realize that 12 does not divide 52, and that there are not 4 weeks to every month. So to give an example that you can fine tune to get exactly what you want, I’ve defined a week to belong to the same month that its thursdays belong to. This dovetails nicely with the ISO 8601 definition of the first week of the year. If there’s a week left, then I add that week to december.
import datetime
from itertools import groupby
def get_week(date):
return date.isocalendar()[1]
def group_by_month(weeks, year):
"""
Group a list containing one item per week, starting with week 1, by month.
If there are too few items to fill a year, stop after last item.
If there are more items than weeks in the year, stop before new year.
"""
day = datetime.timedelta(days=1)
week = datetime.timedelta(days=7)
# Find first Thursday (it's in week 1 by ISO 8601)
date = datetime.date(year, 1, 1)
while date.weekday() != 3:
date += day
# Create list of one day from each week
thursdays = []
while date.year == year:
thursdays.append(date)
date += week
# Check if the last day is in the last week and if not,
# add the week of the last day
last = tursdays[-1]
if get_week(last.replace(day=31)) != get_week(last):
# this will not be a Thursday, but what the hey
thursdays.append(last.replace(day=31))
# The thursdays are already sorted by month, so
# it's OK to use groupby without sorting first
for k, g in groupby(zip(weeks, thursdays), key=lambda x: x[1].month):
yield [x[0] for x in g]
list_1 = [500] * 52
print map(sum, group_by_month(list_1, 2012))
Result:
[2000, 2000, 2500, 2000, 2500, 2000, 2000, 2500, 2000, 2000, 2500, 2000]
You should also be aware of the fact that the year may contain 53 weeks, and if so you must supply a 53-item list instead of a 52-item list. If you don’t, the 53rd week is simply ignored.
2
solved Python: Nested If Looping