Получение первого и последнего элемента в цикле python for - PullRequest
6 голосов
/ 13 июня 2009

Есть ли элегантный и питонный способ отловить первый и последний элемент в цикле for, который перебирает генератор?

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

Этот код пытается получить первый день недели, в котором заканчивается месяц, и последний день недели, в котором заканчивается месяц. Пример: в июне месячный старт должен оцениваться до 31.05.09. Хотя технически это майский день, это первый день недели, с которого начинается июнь.

Месяц-дата - это генератор, поэтому я не могу сделать [: -1]. Какой лучший способ справиться с этим?

Ответы [ 4 ]

11 голосов
/ 13 июня 2009

У Ричи правильная идея. Simpler:

month_dates = cal.itermonthdates(year, month)
month_start = month_dates.next()
for month_end in month_dates: pass # bletcherous
10 голосов
/ 13 июня 2009

Я бы просто включил его в список в начале:

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]

Поскольку может быть только 42 дня (с учетом начального и конечного контекста), это незначительно влияет на производительность.

Кроме того, использование воскресенья лучше, чем магическое число.

10 голосов
/ 13 июня 2009

Как насчет этого?

for i, date in enumerate(month_dates):
    if i == 0:
        month_start = date

month_end = date

enumerate() позволяет найти первый, а переменная date выпадает из цикла, давая вам последний.

2 голосов
/ 13 июня 2009

Для этой конкретной проблемы, я думаю, я бы согласился с решением Мэтью Флашена. Это кажется мне самым простым.

Если ваш вопрос предназначен для более общего подхода, хотя, для любого генератора (с неизвестным и, возможно, большим количеством элементов), тогда лучше использовать подход RichieHindle. Моя небольшая модификация его решения не состоит в том, чтобы перечислять и проверять элемент 0, а просто явно захватить первый элемент:

month_dates = cal.itermonthdates(year, month)
month_start = month_dates.next()
for date in month_dates:
    pass
month_end = date
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...