0

场景:我试图将一个月的所有日子传递给一个列表,我可以在其中迭代和使用函数,例如 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)

我收到前面提到的错误。

问题:关于如何正确/更有效地做到这一点的任何想法?

最终目标:是创建一个函数,将月、年、周和工作日作为输入,并返回一个日期时间对象。

4

2 回答 2

1

大概是这样的

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,在这种情况下你将门列表列表,即列出ot周,每周也是一个列表

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()))

请注意,它将暴露整周,例如在这种情况下,它将从 2018 年 12 月 31 日开始。

于 2018-12-10T11:36:30.697 回答
1

问题是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 比 implicit 好

于 2018-12-10T13:23:05.827 回答