3 回答

TA貢獻1815條經驗 獲得超10個贊
這是一個使用以下方法的巧妙解決方案itertools.chain
:我假設輸入范圍不重疊。如果確實如此,則需要首先使用范圍并集算法對其進行簡化。
from itertools import chain
def range_gaps(a, b, ranges):
? ? ranges = sorted(ranges)
? ? flat = chain((a-1,), chain.from_iterable(ranges), (b+1,))
? ? return [[x+1, y-1] for x, y in zip(flat, flat) if x+1 < y]
舉range_gaps(1, 100, [[10, 50], [90, 100]])
個例子:
首先對范圍進行排序,以防它們尚未按順序排列。如果保證它們是有序的,則不需要這一步。
然后
flat
是一個迭代器,它將給出序列0, 10, 50, 90, 100, 101
。由于
flat
是惰性評估的,并通過迭代消耗它,zip(flat, flat)
因此給出了像 之類的對序列(0, 10), (50, 90), (100, 101)
。所需的范圍就像
(1, 9), (51, 89)
和 的情況一樣(100, 101)
,應該給出一個空范圍,因此它被丟棄。

TA貢獻1799條經驗 獲得超6個贊
假設列表僅包含整數,并且子范圍按遞增順序且不重疊,您可以使用以下代碼。
此代碼將一一獲取所有子范圍,并將與原始完整范圍及其之前的子范圍進行比較,以找到丟失的范圍。
[start,end]=[1,100]
chunks=[[25,31],[7,15],[74,83]]
print([r for r in [[start,chunks[0][0]-1] if start!=chunks[0][0] else []] + [[chunks[i-1][1]+1, chunks[i][0]-1] for i in range(1,len(chunks))]+[[chunks[-1][1]+1,end] if end!=chunks[-1][1] else []] if r])
輸入
[1,100]
[[7,15],[25,31],[74,83]]
輸出
[[1, 6], [16, 24], [32, 73], [84, 100]]
如果不能保證子范圍的遞增順序。您可以包含以下行來對塊進行排序。
chunks.sort(key=lambda x: x[0])

TA貢獻1873條經驗 獲得超9個贊
這是一個通用的解決方案:
def gap(N, ranges):
ranges=[(min1, max1), (min2, (max2), ......, (minn, maxn)]
original=set(range(N))
for i in ranges:
original=original-set(range(i[0], i[1]))
return original
添加回答
舉報