2017-08-30 89 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