Учитывая множество диапазонов чисел, получите все числа в этих диапазонах?

В Python вы можете получить числа в диапазоне, вызывая range(x,y) . Но, учитывая два диапазона, скажем, 5-15 и 10-20 как вы можете получить все числа 5-20 без дубликатов? Диапазоны также могут быть непересекающимися.

Я мог бы выполнить все результаты, а затем разобрать список, но является ли это самым быстрым решением?

 >>> 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)) 

Нужна ли сортировка? Это просто expository, но тогда я не вижу, что набор обязательно выводится в отсортированном порядке:

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

Или вы можете присоединиться к перекрывающимся диапазонам:

 >>> 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]] 

Сортируйте диапазоны (x, y) , увеличивая значения x . Теперь для каждого диапазона, если он перекрывает предыдущий диапазон, установите текущее значение «большого диапазона» в значение y для текущего диапазона. Если этого не произойдет, запустите новый «большой диапазон»: этот не будет перекрывать ни один из предыдущих. Если текущий диапазон полностью включен в текущий большой, игнорируйте его.

Для количества, которое вам нужно, я просто просто прост

 >>> 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]