Python 如何将日期列表与模式匹配?
我有一个PythonPython 如何将日期列表与模式匹配?,python,algorithm,python-2.7,pattern-matching,Python,Algorithm,Python 2.7,Pattern Matching,我有一个Python列表,包含元组,有三个对象:一个字符串(例如:标题),日期,另一个字符串(例如:名称) 示例: scientific_works = [ ('SW 1', datetime.date(2000, 10, 15), 'auth 1'), ('SW 2', datetime.date(2000, 11, 3), 'auth 1'), ('SW 3', datetime.date(2000, 11, 4), 'auth 1'), ('SW 4', d
列表
,包含元组
,有三个对象:一个字符串
(例如:标题),日期
,另一个字符串
(例如:名称)
示例:
scientific_works = [
('SW 1', datetime.date(2000, 10, 15), 'auth 1'),
('SW 2', datetime.date(2000, 11, 3), 'auth 1'),
('SW 3', datetime.date(2000, 11, 4), 'auth 1'),
('SW 4', datetime.date(2000, 12, 1), 'auth 1'),
]
那么我有一个模式:
scientific_works = [
('SW 1', datetime.date(2000, 10, 15), 'auth 1'),
('SW 2', datetime.date(2000, 11, 3), 'auth 1'),
('SW 3', datetime.date(2000, 11, 4), 'auth 1'),
('SW 4', datetime.date(2000, 12, 1), 'auth 1'),
]
从date
到date
,(至少)每int
天/周/月/年int
列表中的项目
例如:
from datetime.date(2000, 11, 1)
until datetime.date(2000, 11, 30)
1 item per day
>>> from datetime import date, timedelta
>>> list(daterange(date(2000, 1, 1), date(2000, 2, 1), timedelta(days=7)))
[datetime.date(2000, 1, 1), datetime.date(2000, 1, 8),
datetime.date(2000, 1, 15), datetime.date(2000, 1, 22),
datetime.date(2000, 1, 29)]
我希望算法执行的操作:
- 给定该列表和该模式,筛选的项是否与规则匹配
1个项目每天完成
,但是,由于没有一个项目
,因此算法将返回false
另一个例子:
- 每个整数2(天/周/月)是否有(至少)整数1数量的项目(工程)?
- 每天工作1次意味着给定日期范围内每1天至少有1件物品。每周2个工作意味着在日期范围内每周至少2个工作(或7天工作区)李>
- 我如何构造一个算法,为它提供一个列表和一个规则模式(每y天、每周、每月或每年x个项目),并查看它是否匹配
int
范围内创建一个循环谢谢。你能举一个更好的例子说明比赛必须遵循的规则吗?您是否在寻找每个作者在每个时间段的特定数量的项目?或者,您是否在一段时间内查找某些条目,然后找到它们属于谁?这将影响到这类人 我认为你最终将不得不对这些数据使用一种排序算法,如果你用正确的方法,这并不可怕 从你问题的底部来看,我认为如果你每n个时间段(天/周/月)搜索x个项目,然后确定作者,可能会有点混乱。如果您的作者数量有限,则可能更容易将其翻转过来,为每个作者创建一个数组,并将项目和日期存储在其中。然后,您只需在每个作者身上运行一个测试循环,检查他们的所有条目,看看它们是否符合要求
对于Python课程,麻省理工学院开放式课程6.00版的计算机科学和编程入门非常好。可以在>中找到,我将使用以下设计:主生成器函数,它迭代工作序列并生成“良好”的工作序列;以及一组可插入的过滤器,它们实现特定的规则,例如日期范围、每天N项、每周N项、每月N项等 下面是一个小例子来说明这个想法:
from datetime import date
from pprint import pprint
scientific_works = [
('SW 1', date(2000, 10, 15), 'auth 1'),
('SW 2', date(2000, 11, 3), 'auth 1'),
('SW 3', date(2000, 11, 4), 'auth 1'),
('SW 4', date(2000, 11, 5), 'auth 1'),
('SW 5', date(2000, 12, 1), 'auth 1'),
('SW 6', date(2000, 12, 15), 'auth 1'),
('SW 7', date(2000, 12, 18), 'auth 1'),
('SW 8', date(2000, 12, 22), 'auth 1'),
]
def filter_works(works, *filters):
for work in works:
good = True
for fil in filters:
good = good and fil(work)
if good:
yield work
class RangeFilter(object):
def __init__(self, from_date, to_date):
self.from_date = from_date
self.to_date = to_date
def __call__(self, work):
return self.from_date <= work[1] <= self.to_date
class WorksPerMonthFilter(object):
def __init__(self, limit):
self.limit = limit
self._current_month = date.min
self._current_number = 0
def __call__(self, work):
month = date(work[1].year, work[1].month, 1)
if month == self._current_month:
self._current_number += 1
else:
self._current_month = month
self._current_number = 1
return self._current_number <= self.limit
if __name__ == '__main__':
pprint(list(filter_works(scientific_works, RangeFilter(date(2000, 10, 1), date(2000, 11, 30)), WorksPerMonthFilter(2))))
pprint(list(filter_works(scientific_works, RangeFilter(date(2000, 10, 1), date(2000, 12, 31)), WorksPerMonthFilter(2))))
pprint(list(filter_works(scientific_works, RangeFilter(date(2000, 10, 1), date(2000, 12, 31)), WorksPerMonthFilter(3))))
from datetime导入日期
从pprint导入pprint
科学著作=[
('SW 1',日期(2000年10月15日),'auth 1'),
('SW 2',日期(2000年11月3日),'auth 1'),
('SW 3',日期(2000年11月4日),'auth 1'),
('SW 4',日期(2000年11月5日),'auth 1'),
(“西南5号”,日期(2000年12月1日),“认证1号”),
('SW 6',日期(2000年12月15日),'auth 1'),
('SW 7',日期(2000年12月18日),'auth 1'),
('SW 8',日期(2000年12月22日),'auth 1'),
]
def过滤器工作(工作,*过滤器):
对于在建工程:
好=真
对于fil in过滤器:
良好=良好和良好(工作)
如果良好:
屈服功
类范围筛选器(对象):
定义初始日期(自我、从日期到日期):
self.from_date=from_date
self.to_date=to_date
定义呼叫(自我、工作):
如果模式为:
from start_date
until end_date
X items per period
其中:
def daterange(start_date, end_date, period):
d = start_date
while d < end_date:
yield d
d += period
现在回到关于stackoverflow的最常见问题。你试过什么?@alKid,谢谢你的评论。我实现了日期范围的第一次过滤。剩下的部分,我在纸上画了模式,并试图提出一个过程(算法),但我失败了,因为我不知道从哪里开始。时间段是从开始日期还是从日历日期开始?例如,[date(2000,6,15),date(2001,1,1)]
列表是否匹配模式:从datetime.date(2000,6,14)到datetime.date(2001,6,1)每年2项
?结束日期和开始日期是否包含在内并不重要。基本上,这个算法是为了看看,一位科学家说,从开始到结束,是否每月发表一篇或更多的论文,或者一个骑自行车的人是否每周练习一次,或者一个学生是否每天上学一次,持续5天。要筛选的日期范围是最简单的,我已经介绍过了,但其他部分——将模式匹配到列表true/false被证明是困难的。谢谢,非常感谢您的帮助@菲尔:这不是包容性的问题。该列表包含两个不同的日历年-每年一个日期。但当一年(如<365.25天)即每年两个项目时,日期之间的差异较小。你看到矛盾了吗?你能回答上一个问题吗