当前位置:  开发笔记 > 编程语言 > 正文

所有星期二和星期三都在一个日期范围内:是否有更多的pythonic方式?

如何解决《所有星期二和星期三都在一个日期范围内:是否有更多的pythonic方式?》经验,为你挑选了1个好方法。

我想datetime在2015-11-02和2015-12-14之间找到所有星期二和星期三(作为对象).这有效:

from datetime import datetime, timedelta

l = []
for i in range(100):
   d = datetime(2015,11,2) + timedelta(days=i)
   if d > datetime(2015,12,14):
       break
   if d.weekday() == 1 or d.weekday() == 2:   # tuesday or wednesday
       l.append(d)
print l   

[datetime.datetime(2015,11,3,0,0),datetime.datetime(2015,11,4,0​​,0),datetime.datetime(2015,11,10,0,0),datetime.datetime( 2015,11,11,0,0),datetime.datetime(2015,11,17,0,0),datetime.datetime(2015,11,18,0,0),datetime.datetime(2015,11,24) ,0,0),datetime.datetime(2015,11,25,0,0),datetime.datetime(2015,12,1,0,0),datetime.datetime(2015,12,2,0,0) ,datetime.datetime(2015,12,8,0,0),datetime.datetime(2015,12,9,0,0)]

有更多的pythonic方式吗?



1> Padraic Cunn..:
from datetime import datetime, timedelta

start, end = datetime(2015, 11, 2), datetime(2015, 12, 14)
days = (start + timedelta(days=i) for i in range((end - start).days + 1))
l = [d for d in days if d.weekday() in [1,2] ]

如果你需要很长的时间,这将会快得多:

def helper(d, i, inc):
    while d.weekday() != i:
        d += timedelta(days=inc)
    return d.replace(hour=0, minute=0, second=0, microsecond=0)


start, end = datetime(2015, 11, 02), datetime(2015,12, 14)


def find_days(st, end, d1, d2):
    if st >= end:
        raise ValueError("Start must be before end")
    else:
        _st, _end = helper(st, d1, inc=-1), helper(end, d2, 1)
        secs = (_end - _st).total_seconds() // 86400
        if st.weekday() == d2:
            yield st
        for i in range(int(secs / 7) + 1):
            if st <= _st <= end:
                yield _st
                nxt = _st + timedelta(days=1)
                if nxt <= end:
                    yield nxt
            _st += timedelta(days=7)
    if _st <= end:
        yield _st
    from pprint import pprint as pp



from pprint import pprint as pp


pp(list(find_days(start, end, 1, 2)))

输出:

[datetime.datetime(2015, 11, 3, 0, 0),
 datetime.datetime(2015, 11, 4, 0, 0),
 datetime.datetime(2015, 11, 10, 0, 0),
 datetime.datetime(2015, 11, 11, 0, 0),
 datetime.datetime(2015, 11, 17, 0, 0),
 datetime.datetime(2015, 11, 18, 0, 0),
 datetime.datetime(2015, 11, 24, 0, 0),
 datetime.datetime(2015, 11, 25, 0, 0),
 datetime.datetime(2015, 12, 1, 0, 0),
 datetime.datetime(2015, 12, 2, 0, 0),
 datetime.datetime(2015, 12, 8, 0, 0),
 datetime.datetime(2015, 12, 9, 0, 0)]

这就像dateutil那样做,并且做得更快:

In [12]: def dte():
....:         results = rrule(DAILY,
....:                 dtstart = dt.datetime(2015,11, 2),
....:                 until = end,
....:                 byweekday=(TU, WE),
....:         )
....:         return list(results)
....: 


In [38]: start, end = datetime(2015, 11, 2), datetime(2100, 11, 14)

In [39]: for i in range(600):
             end += timedelta(days=1)
             assert dte() == list(find_days(start, end,1,2 ))
   ....:     

In [40]: start, end = datetime(2015, 11, 2), datetime(2017, 11, 14)


In [41]: timeit  [d for d in date_range(start, end) if d.weekday() in (1, 2)]
10 loops, best of 3: 62.1 ms per loop

In [42]: timeit list(find_days(start, end, 1, 2))
100 loops, best of 3: 8.11 ms per loop

In [43]: timeit dte()
10 loops, best of 3: 131 ms per loop

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有