Фильтрация дат, полученных из monthdatescalendar, дает AttributeError: объект «список» не имеет атрибута «день недели» - PullRequest
0 голосов
/ 10 декабря 2018

Сценарий: Я пытаюсь передать все дни месяца в список, в котором я могу перебирать и использовать функции по дням, например, weekday ().

Проблема: До сих пор я мог использовать Календарь, чтобы передавать даты или дни в список.В обоих случаях, когда я пытаюсь прочитать даты и вывести только требуемый день недели, я получаю ошибку:

AttributeError: 'list' object has no attribute 'weekday'

Что я сделал до сих пор (с помощью других постов здесь на SO):

Это работает нормально, но мне нужно, чтобы оно было более динамичным

import calendar
cal = calendar.Calendar()
cal.monthdatescalendar(2019, 1)[0][1]
cal.monthdatescalendar(2019, 1)[0][1].weekday()
r = [foo for foo in cal.monthdatescalendar(2019, 1)]

Итак, я попытался:

r = [foo for foo in calendar.monthcalendar(2019, 1)]
list(r)

и

r = [foo for foo in cal.monthdatescalendar(2019, 1)]
list(r)

Все это прекрасно работает, но когда я пытаюсь выполнить итерацию, например:

r = [foo for foo in cal.monthdatescalendar(2019, 1)]
if r[1].weekday() == 1:
    list(r)

или

r = [foo for foo in cal.monthdatescalendar(2019, 1) if foo[1].weekday() == 1]
list(r)

Я получаю ранее упомянутую ошибку.

Вопрос: Есть идеи о том, как сделать это правильно / более эффективно?

Конечная цель: Создать функцию, которая принимает в качестве входных данных месяц, год, неделю и день недели и возвращает мне объект datetime.

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Проблема в том, что monthdatescalendar возвращает вложенный список:

>>> import calendar
>>> cal = calendar.Calendar()
>>> cal.monthdatescalendar(2019, 1)
[[datetime.date(2018, 12, 31),
  datetime.date(2019, 1, 1),
  datetime.date(2019, 1, 2),
  datetime.date(2019, 1, 3),
  datetime.date(2019, 1, 4),
  datetime.date(2019, 1, 5),
  datetime.date(2019, 1, 6)],
 [datetime.date(2019, 1, 7),
  datetime.date(2019, 1, 8),
  datetime.date(2019, 1, 9),
  datetime.date(2019, 1, 10),
  ...

Итак, если вы хотите сохранить ту же структуру, чтобы получить только вторые днинеделю, вы можете сделать следующее:

>>> filtered_month = [[day for day in week if day.weekday() == 1]
                      for week in cal.monthdatescalendar(2019, 1)]
>>> filtered_month
[[datetime.date(2019, 1, 1)],
 [datetime.date(2019, 1, 8)],
 [datetime.date(2019, 1, 15)],
 [datetime.date(2019, 1, 22)],
 [datetime.date(2019, 1, 29)]]

Другой вариант - использовать itermonthdates, но список будет плоским:

>>> [day for day in cal.itermonthdates(2019, 1) if day.weekday() == 1]
[datetime.date(2019, 1, 1),
 datetime.date(2019, 1, 8),
 datetime.date(2019, 1, 15),
 datetime.date(2019, 1, 22),
 datetime.date(2019, 1, 29)]

Также обратите вниманиечто вы можете указать первый день календаря при создании объекта Calendar.Затем, чтобы получить первые дни недели, вам просто нужно взять первые элементы списков:

>>> cal = calendar.Calendar(calendar.TUESDAY)
>>> [week[0] for week in cal.monthdatescalendar(2019, 1)]
[datetime.date(2019, 1, 1),
 datetime.date(2019, 1, 8),
 datetime.date(2019, 1, 15),
 datetime.date(2019, 1, 22),
 datetime.date(2019, 1, 29)]

PS:
В качестве примечания, я думаю, что этолучше сравнить дни явно следующим образом:

if day.weekday() == calendar.TUESDAY:
    ...

вместо

if day.weekday() == 1:
    ...

Поскольку Explicit лучше, чем неявный .

0 голосов
/ 10 декабря 2018

Возможно, что-то вроде этого

import calendar

cal = calendar.Calendar(firstweekday=0) # firstweekday is an integer specifying the first day of the week. 0 is Monday (the default), 6 is Sunday.
for my_date in cal.itermonthdates(year=2019, month=1):
    print('{}. Weekday is {}'.format(my_date.strftime('%A, %Y-%m-%d'), my_date.weekday()))

или если вы хотите использовать monthdatescalendar, в этом случае вы будете управлять списком списка, то есть списком недель, и каждая неделя также является списком

import calendar

cal = calendar.Calendar(firstweekday=0) # firstweekday is an integer specifying the first day of the week. 0 is Monday (the default), 6 is Sunday.
for week in cal.monthdatescalendar(year=2019, month=1):
    for my_date in week:
        print('{}. Weekday is {}'.format(my_date.strftime('%A, %Y-%m-%d'), my_date.weekday()))

Обратите внимание, что он будет предоставлять полные недели, например, в этом случае он начнется с 31 декабря 2018 года.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...