bisect
モジュールによって示されるアルゴリズムを使用すると、検索時間が最も速くなりますが、いくつかのソートされたインデックスを作成する必要があります。
リスト内のエントリのインデックスを使用して、開始時刻と終了時刻の両方をリストに保存する必要がありa
ます。
starttimes = [(l[0], i) for i,l in enumerate(a)]
starttimes.sort()
endtimes = [(l[1], i) for i, l in enumerate(a)]
endtimes.sort()
次に、 and関数bisect
に基づいて特殊な関数を作成します。bisect.bisect_left
bisect.bisect_right
def bisect_timeseries_start(starttimes, start):
while lo < hi:
mid = (lo+hi)//2
if starttimes[mid][0] < start: lo = mid+1
else: hi = mid
return starttimes[lo][1]
def bisect_timeseries_end(endtimes, end):
while lo < hi:
mid = (lo+hi)//2
if end < endtimes[mid][0]: hi = mid
else: lo = mid+1
return endtimes[lo][1]
これで、次の関数を使用して開始インデックスと終了インデックスを見つけることができます。
startindex = bisect.bisect_timeseries_start(starttimes, start)
endindex = bisect.bisect_timeseries_end(endtimes, end)
一致する範囲を返すのが簡単になりました。
startendrange = a[startindex:endindex]
各検索にはO(lg n)
コストがかかります。ここn
で、はリストの長さです。a
これらの操作を組み合わせて、時系列リストとインデックスの両方をカプセル化するクラスにするのは簡単です。