[英]How to match a list of dates to a pattern?
我有一个带有三个对象的tuples
的Python list
:一个string
(例如:title), date
和另一个string
(例如:name)。
例:
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
从项目list
每int
天/周/月/年
例:
from datetime.date(2000, 11, 1)
until datetime.date(2000, 11, 30)
1 item per day
我想要该算法做什么:
在示例的情况下,此模式将匹配2个项目,所有这些项目均符合此处的规则: 1 item complete per day
,但是,由于每天的区块中都没有an item
,因此算法将返回false
。
另一个例子:
我可以遍历列表,并找出哪些项目匹配from
和until
模式,当然。
但是,对于将它们与其余规则进行匹配,以查看其是肯定的还是否定的,我确实感到困惑。
我的问题:
我正在为应用程序的一个小组件工作,无论作者是否解锁奖励,给定的数据(列表)和规则(模式)。
我已经完成了udacity的几个Python类,包括大多数算法,但确实找不到解决方法。
到目前为止,我想到了这一点:
int
范围内创建一个循环。 但是,这不起作用,我也不认为将块转换为几天是完全有效的。
谢谢。
您能否发布一个更好的示例来说明比赛必须遵循的规则? 您是否在每个时间段寻找每位作者一定数量的项目? 或者,您是在一段时间内寻找某些条目,然后找到它们所属的人? 这将影响排序。
我认为您最终将不得不对这些数据使用排序算法,如果以正确的方式进行操作,这并不可怕。
从问题的底部开始,我认为如果您每n个时间段(天/周/月)搜索x项,然后确定作者,则可能会有些混乱。 如果您的作者人数有限,可能更容易将其翻转并为每个作者创建一个数组,然后将项目和日期存储在其中。 然后,您只需对每个作者运行一个测试循环,即可检查他们的所有条目以查看它们是否符合要求。
对于Python类,MIT OpenCourseware的6.00《计算机科学与编程简介》非常好。 可以在以下网址找到它: http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/ >
我将使用以下设计:主生成器函数,它在工作序列上进行迭代并产生“好”的函数; 以及一组可实现特定规则的可插拔过滤器,例如日期范围,每天,每周,每月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 start_date until end_date X items per period
然后找出是否scientific_works
图案,的模拟匹配numpy.histogram()
函数可以使用:
import datetime
import numpy as np
ts = datetime.date.toordinal # or any monotonic numeric `date` function
hist = np.histogram(map(ts, (date for title, date, name in scientific_works)),
bins=map(ts, daterange(start_date, end_date, period))[0]
does_it_match = all(x >= X for x in hist)
哪里:
def daterange(start_date, end_date, period):
d = start_date
while d < end_date:
yield d
d += period
例:
>>> 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)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.