python - 从两个日期生成日期列表的最Pythonic方法是什么

标签 python

我想生成两个日期之间的日期列表(一周的第 N 天)。

例如,给定日期“20111101”和“20111201”,假设我想生成该月的第三个星期三的日期,我想生成日期:

["20111116", "20111221"]

所以我想写一个这样的函数:

def generateNthWeekdayDatesList(startdate, enddate, nthday=3, dayofweek="wed"):
    pass

实现此功能的最佳(即最Pythonic)方法是什么?

最佳答案

这是使用generator的情况非常适合/pythonic。

def nth_day_of_month(start, end, nth, weekday):
    assert start.day == 1, "start on the first day of a month"
    assert nth > 0
    assert 1 <= weekday <= 7

    candidate = start
    seen_in_month = 0
    while candidate <= end:
        if candidate.isoweekday() == weekday:
            seen_in_month += 1
            if seen_in_month == nth:
                yield candidate
                current_month = candidate.month
                while candidate.month == current_month:
                    candidate += timedelta(1)
                seen_in_month = 0
            else:
                if (candidate + timedelta(1)).month != candidate.month:
                    seen_in_month = 0
                candidate += timedelta(1)
        else:
            if (candidate + timedelta(1)).month != candidate.month:
                seen_in_month = 0
            candidate += timedelta(1)


# third wednesday
print list(nth_day_of_month(date(2011, 1, 1), date(2012, 1, 1), nth=3, weekday=3))

# fifth sunday
print list(nth_day_of_month(date(2011, 1, 1), date(2012, 1, 1), nth=5, weekday=7))

# 9th monday
print list(nth_day_of_month(date(2011, 1, 1), date(2012, 1, 1), nth=9, weekday=1))

您甚至可以创建一个无限的生成器(永不停歇的生成器):

def infinite_nth_day_of_month(start, nth, weekday):
    assert start.day == 1, "start on the first day of a month"
    assert nth > 0
    assert 1 <= weekday <= 7

    candidate = start
    seen_in_month = 0
    while True:
        if candidate.isoweekday() == weekday:
            seen_in_month += 1
            if seen_in_month == nth:
                yield candidate
                current_month = candidate.month
                while candidate.month == current_month:
                    candidate += timedelta(1)
                seen_in_month = 0
            else:
                if (candidate + timedelta(1)).month != candidate.month:
                    seen_in_month = 0
                candidate += timedelta(1)
        else:
            if (candidate + timedelta(1)).month != candidate.month:
                seen_in_month = 0
            candidate += timedelta(1)

# this will create an infinite list, not a good idea
# print list(infinite_nth_day_of_month(date(2011, 1, 1), 3, 3))

import itertools

date_generator = infinite_nth_day_of_month(date(2011, 1, 1), 3, 3)
# create a list the 10000 third wednesdays of 2011 and into the future
date_list = list(itertools.islice(date_generator, 10000))

>>> print date_list[0]
2011-01-19
>>> print date_list[-1]
2844-04-20

请参阅 itertools 的文档.

如果提供给无限生成器的参数创建了一个永远不会产生任何东西的生成器(例如第 9 个星期二),那么它就不好了。在这种情况下,它将无休止地搜索,直到达到 datetime.date 支持的最大日期并引发 OverflowError:日期值超出范围

关于python - 从两个日期生成日期列表的最Pythonic方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8613565/

相关文章:

javascript - Python 中使用 Selenium 停止动态页面滚动

python - 计算python中每n行数据帧的最大值/最小值

python - 数据错误 : No numeric types to aggregate

python - 使用零填充和隐含小数格式化 float

python - 如何使用 pymongo 编写连接到 mongodb 的函数

Python 文本文件字符串放入电子表格的列中

python - python中的多个返回值

python - 按下按钮时打印 LineEdit 文本

python - 使用 Python 发出下载视频的请求

python - 如何在django post_save监听器中获取请求对象