Reputation: 19495
Is there an elegant and pythonic way to trap the first and last item in a for loop which is iterating over a generator?
from calendar import Calendar
cal = Calendar(6)
month_dates = cal.itermonthdates(year, month)
for date in month_dates:
if (is first item): # this is fake
month_start = date
if (is last item): # so is this
month_end = date
This code is attempting to get the first day of the week the month ends on, and the last day of the week the month ends on. Example: for June, month-start should evaluate to 5/31/09. Even though it's technically a day in May, it's the first day of the week that June begins on.
Month-dates is a generator so i can't do the [:-1] thing. What's a better way to handle this?
Upvotes: 8
Views: 15365
Reputation: 47183
Richie's got the right idea. Simpler:
month_dates = cal.itermonthdates(year, month)
month_start = month_dates.next()
for month_end in month_dates: pass # bletcherous
Upvotes: 11
Reputation: 284836
I would just force it into a list at the beginning:
from calendar import Calendar, SUNDAY
cal = Calendar(SUNDAY)
month_dates = list(cal.itermonthdates(year, month))
month_start = month_dates[0]
month_end = month_dates[-1]
Since there can only be 42 days (counting leading and tailing context), this has negligible performance impact.
Also, using SUNDAY is better than a magic number.
Upvotes: 11
Reputation: 14529
For this specific problem, I think I would go with Matthew Flaschen's solution. It seems the most straightforward to me.
If your question is meant to be taken more generally, though, for any generator (with an unknown and possibly large number of elements), then something more like RichieHindle's approach may be better. My slight modification on his solution is not to enumerate and test for element 0, but rather just grab the first element explicitly:
month_dates = cal.itermonthdates(year, month)
month_start = month_dates.next()
for date in month_dates:
pass
month_end = date
Upvotes: 2
Reputation: 281495
How about this?
for i, date in enumerate(month_dates):
if i == 0:
month_start = date
month_end = date
enumerate()
lets you find the first one, and the date
variable falls out of the loop to give you the last one.
Upvotes: 10