<p>步骤0:为方便起见,创建一个<code>Range</code>类:</p>
<pre><code>from collections import namedtuple
Range = namedtuple("Range", ["start", "end"])
</code></pre>
<p>步骤1:创建一个计算两个范围的交集的函数。此函数适用于包含两个可比较点的任何对象:</p>
^{pr2}$
<p>第2步:创建一个函数,通过尝试所有可能的组合,找到两组范围的所有交点。在</p>
<pre><code>def intersect_two(ranges1, ranges2):
for range1 in ranges1:
for range2 in ranges2:
intersection = intersect(range1, range2)
if intersection:
yield intersection
</code></pre>
<p>步骤3:<a href="https://docs.python.org/3/library/functools.html#functools.reduce" rel="nofollow noreferrer">^{<cd2>}</a>使用<code>intersect_two</code>的范围集列表:</p>
<pre><code>def intersect_all(ranges):
return reduce(intersect_two, ranges)
</code></pre>
<p>为了简单起见,我使用整数,但它应该与<code>datetime</code>对象一样好:</p>
<pre><code>>>> timelines = [
... (Range(0, 11), Range(15, 20)),
... (Range(8, 16), Range(19, 25)),
... (Range(0, 10), Range(15, 22)),
... ]
>>>
>>> for intersection in intersect_all(timelines):
... print(intersection)
...
Range(start=8, end=10)
Range(start=15, end=16)
Range(start=19, end=20)
</code></pre>