[英]Find if dates are overlapping in a list of N pairs
給定開始時間和開始時間的列表,我想查找列表中是否包含重疊的條目:
timesok = [('9:30', '10:00'), ('10:00', '10:30'), ('10:30', '11:00')]
wrongtimes1 = [('9:30', '10:00'), ('9:00', '10:30'), ('10:30', '11:00')]
wrongtimes2=[('9:30', '10:00'), ('10:00', '10:30'), ('9:15', '9:45')]
我從這個非常相似的問題中借用了一些代碼來測試重疊的日期對 :
def test_overlap(dt1_st, dt1_end, dt2_st, dt2_end):
r1 = Range(start=dt1_st, end=dt1_end)
r2 = Range(start=dt2_st, end=dt2_end)
latest_start = max(r1.start, r2.start)
earliest_end = min(r1.end, r2.end)
overlap = (earliest_end - latest_start)
return overlap.seconds
我測試條目列表的功能:
def find_overlaps(times):
pairs = list(combinations(times, 2))
print pairs
for pair in pairs:
start1 = dt.strptime(pair[0][0], '%H:%M')
end1 = dt.strptime(pair[0][1], '%H:%M')
start2 = dt.strptime(pair[1][0], '%H:%M')
end2 = dt.strptime(pair[1][1], '%H:%M')
yield test_overlap(start1, end1, start2, end2) > 0
使用時,它的工作方式如下:
In [257]: list(find_overlaps(timesok))
[(('9:30', '10:00'), ('10:00', '10:30')), (('9:30', '10:00'), ('10:30', '11:00')), (('10:00', '10:30'), ('10:30', '11:00'))]
Out[257]: [False, False, False]
In [258]: list(find_overlaps(wrongtimes1))
[(('9:30', '10:00'), ('9:00', '10:30')), (('9:30', '10:00'), ('10:30', '11:00')), (('9:00', '10:30'), ('10:30', '11:00'))]
Out[258]: [True, False, False]
In [261]: list(find_overlaps(wrongtimes2))
[(('9:30', '10:00'), ('10:00', '10:30')), (('9:30', '10:00'), ('9:15', '9:45')), (('10:00', '10:30'), ('9:15', '9:45'))]
Out[261]: [False, True, False]
然而:
我提出了一種測試重疊的方法,一種找到日期的所有交集的方法:
def test_overlap(dt1_st, dt1_end, dt2_st, dt2_end):
return not (dt1_st < dt2_end and dt1_end >dt2_st)
這涵蓋了重疊的所有可能性
這類似於區間重疊問題。 詳細說明pkacprzak的帖子。
按時間對事件列表進行排序。 保留另一個活動元素列表。
像這樣線性處理
對於每個事件/元素。
另外,請查看間隔重疊的其他此類解決方案。 如何有效地重疊間隔
如果沒有兩個對同時開始,則可以將時間戳記為“自午夜以來的分鍾數”中的數值,然后按開始時間對輸入列表進行排序,然后檢查任何元素的結束時間是否大於開始時間下一個元素的時間:
from operator import itemgetter
from itertools import izip
def asNumber(s):
colon = s.find(':')
return int(s[:colon]) * 60 + int(s[colon+1:])
def isValid(l):
numericPairs = [(asNumber(a), asNumber(b)) for (a,b) in l]
sortedPairs = sorted(numericPairs, key=itemgetter(0))
return all(startB >= endA for ((startA, endA), (startB, endB)) in izip(sortedPairs, sortedPairs[1:]))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.