2017-08-30 4 views
0

のためにpythonで開かれた範囲の比較:あなたが見ることができるようには、次のように私は範囲を比較交差点

def get_intersections(ranges): 
    """Marks ranges if they intersect with other ranges with True. 
    """ 
    intersection_idxs = len(ranges) * [False] 
    for idx in range(len(ranges)): 
     r, rest = set(ranges[idx]), [set(_) for _ in ranges[:idx] + ranges[idx+1:]] 
     # Uncomment to understand. 
     # print(r) 
     # print(rest) 
     if any([len(set.intersection(r, r2)) > 0 for r2 in rest]): 
      intersection_idxs[idx] = True 
    return intersection_idxs 

# Example 1. 
ran1 = range(4,9) 
ran2 = range(2,5) 
ran3 = range(2,3) 
ranges = [ran1, ran2, ran3] 
print(get_intersections(ranges)) 

# Example 2. 
ran1 = range(1,5) 
ran2 = range(2,5) 
ran3 = range(7,9) 
ranges = [ran1, ran2, ran3] 
print(get_intersections(ranges)) 

# Example 3. 
#ran1 = range(1,inf) 
#ran2 = range(2,5) 
#ran3 = range(7,9) 
#ranges = [ran1, ran2, ran3] 
#print(get_intersections(ranges)) 
#>> [True, True, True] 

、最初の2例は非常にうまく機能します。最初の例ではすべての範囲が交差するため、get_intersections関数は[True、True、True]を返します。

最後の範囲(範囲(7,9))は他の範囲と交差しません。したがって、[True、True、False]が返されます。

例3(擬似コード参照)を実現したいと思います。この場合、最初の範囲は1から無限になり、これは他の範囲と交差することを意味します。したがって、他の範囲も自動的に交差します。今私はどのようにこれを行う方法を参照してください。同様の方法で無限遠の範囲または範囲を使用する方法はありますか?

+0

私は、アプリケーションが背後にあるかわからないので、私は私の答えはつもり助けているか分かりません。なぜinfを重要な数値として定義しないのですか?例えば、import sysの場合、inf = sys.maxsizeを使用します。私のコンピュータ上では、これは数字です:9223372036854775807. – Mathieu

+1

@マチューは、それを(あるいはどんな重要な範囲でも)物事を比較するために 'set'を実行するとほとんどのマシンをかなり吹き飛ばすでしょう:) –

+0

うん、 infが境界としてあるかどうかを確認することができます。このような場合は、上位の実在のブーディーリー(例9の場合)を検索し、単純にinfを9 + 1と設定します。ただし、今のようにコードを保持するだけで、Franeソリューションが優れています。 – Mathieu

答えて

0

rangeを使用する理由はわかりません。

(a,b)の上限と下限のタプルを使用できます。

infが必要な場合は、math.infを任意の実数より大きくすることができます。

したがって(a,b)(c,d)と一致する場合は、c<b and a<dです。

+1

ありがとうございましたこれは役に立ちました! – msg

0

あなたはそれを正しく持っています。これは設計上の欠陥でした。ここに私のコードは次のとおりです。

def get_intersections(lis): 
    """Marks ranges if they intersect with other ranges with True. 
    """ 
    intersection_idxs = len(ranges) * [False] 
    for idx in range(len(lis)): 
     r, rest = lis[idx], ranges[:idx] + ranges[idx+1:] 
     # Uncomment to understand. 
     # print(r) 
     # print(rest) 
     if any([r2[0] <= r[1] and r[0] <= r2[1] for r2 in rest]): 
      intersection_idxs[idx] = True 
    return intersection_idxs 

# Example 1. 
ranges = [(4,9), (2,5), (2,3)] 
assert(get_intersections(ranges) == 3 * [True]) 
# Example 2. 
ranges = [(1,5), (2,5), (7,9)] 
assert(get_intersections(ranges) == [True, True, False]) 
# Example 3. 
ranges = [(1,float('inf')), (2,5), (7,9)] 
assert(get_intersections(ranges) == [True, True, True]) 
# Example 4. 
ranges = [(1,2), (4,float('inf')), (7,9)] 
assert(get_intersections(ranges) == [False, True, True]) 
+0

この場合も下限に 'float( ' - inf')'を使うことができます。 –

+0

ありがとうございます! – msg