作为一个普遍关注的问题,我想知道是否有更优雅/更有效的方法来做到这一点。我有一个函数比较两个日期的开始/结束元组,如果它们相交,则返回true。
from datetime import date
def date_intersection(t1, t2):
t1start, t1end = t1[0], t1[1]
t2start, t2end = t2[0], t2[1]
if t1end < t2start: return False
if t1end == t2start: return True
if t1start == t2start: return True
if t1start < t2start and t2start < t1end: return True
if t1start > t2start and t1end < t2end: return True
if t1start < t2start and t1end > t2end: return True
if t1start < t2end and t1end > t2end: return True
if t1start > t2start and t1start < t2end: return True
if t1start == t2end: return True
if t1end == t2end: return True
if t1start > t2end: return False
所以如果:
d1 = date(2000, 1, 10)
d2 = date(2000, 1, 11)
d3 = date(2000, 1, 12)
d4 = date(2000, 1, 13)
然后:
>>> date_intersection((d1,d2),(d3,d4))
False
>>> date_intersection((d1,d2),(d2,d3))
True
>>> date_intersection((d1,d3),(d2,d4))
True
等
我很想知道是否有一个更pythonic /更优雅/更有效/更简洁/更好的方式来做这个可能mxDateTime或一些聪明的黑客与timedelta或set()?
另一个有用的形式是函数返回交集的开始/结束元组(如果找到一个)
由于
答案 0 :(得分:20)
这不是更多的Pythonic,但你可以简单地用逻辑来决定一个交叉点。这个特殊的问题出现了很多:
return (t1start <= t2start <= t1end) or (t2start <= t1start <= t2end)
要了解为什么这个有效可以考虑两个区间可以交叉的不同可能方式,并看到一个区间的起点必须始终在另一个区间的范围内。
答案 1 :(得分:7)
另一种希望更容易理解的解决方案:
def has_overlap(A_start, A_end, B_start, B_end):
latest_start = max(A_start, B_start)
earliest_end = min(A_end, B_end)
return latest_start <= earliest_end:
我们可以轻松获得重叠的间隔,它是(latest_start, earliest_end)
。请注意,latest_start可以等于earliest_end。
应该注意,这假定为A_start <= A_end
和B_start <= B_end
。
答案 2 :(得分:6)
这是一个为您提供交叉范围的版本。恕我直言,它可能不是最优化的条件,但它清楚地显示t2何时与t1重叠。如果您只想要真/假,可以根据其他答案进行修改。
if (t1start <= t2start <= t2end <= t1end):
return t2start,t2end
elif (t1start <= t2start <= t1end):
return t2start,t1end
elif (t1start <= t2end <= t1end):
return t1start,t2end
elif (t2start <= t1start <= t1end <= t2end):
return t1start,t1end
else:
return None
答案 3 :(得分:3)
Final Comparison: start <= other_finish and other_start <= finish
# All of the conditions below result in overlap I have left out the non overlaps
start <= other_start | start <= other_finish | other_start <= finish | finish <= other_finish
0 1 1 0
0 1 1 1
1 1 1 0
1 1 1 1
只有开始&lt; = other_finish 和 other_start&lt; = finish 才能返回重叠。
答案 4 :(得分:2)
intersection_length = min(t1end, t2end) - max(t1start, t2start)
return intersection_length >= 0
这将接受由单个点组成的交点;否则请使用> 0
。
直觉是相交的间隔(如果存在)从最高起点开始,在最低终点结束。有两种可能性:
这是一个正确的间隔,长度可能为零。
起点和终点最终被切换。这意味着两个间隔之间有一个间隙,您可以将其称为“负相交”。
答案 5 :(得分:0)
if t1end < t2start or t1start > t2end: return False
if t1start <= t2end or t2start <= t1start: return True
return False
那不会涵盖所有交叉集吗?