如何简单检查一个区间是否是另一个区间的子区间?
range1 in range2
的效果并不符合预期。
如何简单检查一个区间是否是另一个区间的子区间?
range1 in range2
的效果并不符合预期。
O(1)
时间内完成操作:def range_subset(range1, range2):
"""Whether range1 is a subset of range2."""
if not range1:
return True # empty range is subset of anything
if not range2:
return False # non-empty range can't be subset of empty range
if len(range1) > 1 and range1.step % range2.step:
return False # must have a single value or integer multiple step
return range1.start in range2 and range1[-1] in range2
使用中:
>>> range_subset(range(0, 1), range(0, 4))
True
set((range(0,1))).issubset(range(0,4))
可以完成它。
我曾经遇到过类似的问题:如何判断两个范围是否重叠。因此,函数中引入范围的顺序对我来说是一个限制(顺序不应该影响结果)。这是我提出的解决方案(受@jonrsharpe答案的启发):
def range_overlap(range1, range2):
"""Whether range1 and range2 overlap."""
x1, x2 = range1.start, range1.stop
y1, y2 = range2.start, range2.stop
return x1 <= y2 and y1 <= x2
a = range(20, 25, 2)
b = range(23, 25, 3) # different step does not matter
print(list(a), list(b)) # [20, 22, 24] [23]
range_overlap(a, b) # True
如果任何一个范围为空:
# if range1 is non-empty and range2 is empty
a = range(20, 25, 1)
b = range(22, 22, 3) # empty but the range start and end overlap
assert range_overlap(a, b) == range_overlap(a, b)
range_overlap(a, b)
# True
在我看来,这是最易读的方法,但效率较低:
all(e in range2 for e in range1)
如果两个范围的步长相同,我认为这将是最有效的:
range1[0] in range2 and range1[-1] in range2
range(0,9,3)
和 range(0,8,2)
。 - Kevinrange2
中的步长大于range1
中的步长,无论是否互质。 - J Richard Snapexrange
同样适用,而 xrange
不提供 .step
(或任何)方法。变量 any(...)
可用于检查交集而不是子集。而在使用 range
时谈论大型集合的效率只是愚蠢的。 - Orwellophilerange(1, 1)
-> range(2, 4)
。根据您比较的范围,这可能会变成 all([])
-> True
。all(e in range(2, 4) for e in range(1, 1))
的计算结果为 True
。 - Josmoor98
range_overlap
的新函数,它只需返回range_subset(r1, r2) or range_subset(r2, r1)
,这样做的好处是采用了惰性求值(如果r1
是r2
的子集,则无需检查r2
是否是r1
的子集)。 - jonrsharpe