给定一系列数字,得到这些范围内的所有数字?

时间:2011-07-10 21:15:09

标签: python algorithm

在Python中,您可以通过调用range(x,y)来获取范围内的数字。但是如果给出两个范围,比如说5-1510-20,你怎么能得到所有数字5-20而没有重复?范围也可能是不相交的。

我可以连接所有结果,然后统一列表,但这是最快的解决方案吗?

4 个答案:

答案 0 :(得分:9)

>>> a = range(5, 15)
>>> b = range(10, 20)
>>> print sorted(set(a + b))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

或者,如果您希望将列表更广泛地扩展到其元素中以包含在集合中:

>>> list_of_lists = [a, b]
>>> print sorted(set(elem for l in list_of_lists for elem in l))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

我找到了一种方法可以将它全部组合成一行:

>>> list_of_lists = [a, b]
>>> print set.union(*map(set, list_of_lists))

需要分类吗?它只是说明文件,但后来我没有看到这些集必然按排序顺序输出:

>>> x = set(range(3))
>>> x
set([0, 1, 2])
>>> x.add(-1)
>>> x
set([0, 1, 2, -1])

答案 1 :(得分:2)

或者您可以加入重叠范围:

>>> def join_overlapping_ranges(ranges):
...     list_of_ranges = []
...     # ranges are sorted on first element
...     for r in sorted(ranges):
...         # ranges are stored as [start, end]
...         if list_of_ranges and list_of_ranges[-1][1] >= r[0]:
...             list_of_ranges[-1][1] = r[1]
...         else:
...             list_of_ranges.append(r)        
...     return list_of_ranges
... 
>>> ranges = [[3,4], [5,7], [1,2], [4,6], [5,5]]
>>> print sorted(ranges)
[[1, 2], [3, 4], [4, 6], [5, 5], [5, 7]]
>>> print join_overlapping_ranges(ranges)
[[1, 2], [3, 7]]

答案 2 :(得分:1)

通过增加 x 值对(x,y)范围进行排序。现在,对于每个范围,如果它与前一个范围重叠,请将当前“大范围”的 y 值设置为当前范围的 y 值。如果没有,则启动一个新的“大范围”:这个不会重叠以前的任何一个。如果当前范围完全包含在当前范围内,请忽略它。

答案 3 :(得分:1)

对于您需要的数量,我会保持简单

>>> a = range(5, 15)
>>> b = range(10, 20)
>>> from itertools import chain
>>> sorted(set(chain.from_iterable(list_of_lists)))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]