2017-08-30 133 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] 

正如你所看到的,第一兩個例子工作得非常好。由於第一個示例中所有範圍都相交,所以get_intersections函數返回[True,True,True]。

在第二個示例中,最後一個範圍(範圍(7,9))不與其他範圍相交。因此返回[True,True,False]。

我想實現示例3(請參閱僞代碼)。在這種情況下,第一個範圍從1到無窮大,這意味着它與其他範圍相交。其他範圍因此也自動相交。現在我看不出如何做到這一點。有沒有辦法以類似的方式使用開放範圍或無限範圍?

+0

因爲我不知道應用程序是在後面,我不知道我的答案會幫助。爲什麼不把inf定義爲一個重要的數字?例如,import sys然後使用inf = sys.maxsize。在我的計算機上,這是數字:9223372036854775807. – Mathieu

+1

@Mathieu即使在那個(或任何重要的範圍)上運行'set'來比較事情也會讓很多機器受到影響:) –

+0

嗯,對,電腦不好。你可以檢查你是否有inf作爲邊界。如果是這樣的話,你可以搜索更高的實際boudary(在例子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

你說得對Frane。這是一個設計缺陷。這裏是我的代碼現在:

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