检测列表中的连续整数

我有一个包含这样的数据的列表:

[1, 2, 3, 4, 7, 8, 10, 11, 12, 13, 14] 

我想打印出连续整数的范围:

 1-4, 7-8, 10-14 

有没有内置/快速/有效的方法呢?

从文档 :

 >>> from itertools import groupby >>> from operator import itemgetter >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] >>> for k, g in groupby(enumerate(data), lambda (i, x): ix): ... print map(itemgetter(1), g) ... [1] [4, 5, 6] [10] [15, 16, 17, 18] [22] [25, 26, 27, 28] 

你可以很容易地适应这个打印的范围。

内置:不,据我所知。

你必须通过数组运行。 首先将第一个值放入一个variables并打印出来,然后只要你继续敲下一个数字,别忘了记住另一个variables的最后一个数字。 如果下一个数字不符合,请检查记住的最后一个数字与第一个数字。 如果是一样的,什么也不要做。 如果不同,请打印“ – ”和最后一个数字。 然后把当前值放在第一个variables中,并重新开始。 在数组的最后,你运行相同的例程,就像你已经打出了一个数字。

当然,我可以写代码,但我不想破坏你的功课:-)

这将按照您的指定完全打印:

 >>> nums = [1, 2, 3, 4, 7, 8, 10, 11, 12, 13, 14] >>> ranges = sum((list(t) for t in zip(nums, nums[1:]) if t[0]+1 != t[1]), []) >>> iranges = iter(nums[0:1] + ranges + nums[-1:]) >>> print ', '.join([str(n) + '-' + str(next(iranges)) for n in iranges]) 1-4, 7-8, 10-14 

如果列表中有任何单个数字范围,它们将显示为nn:

 >>> nums = [1, 2, 3, 4, 5, 7, 8, 9, 12, 15, 16, 17, 18] >>> ranges = sum((list(t) for t in zip(nums, nums[1:]) if t[0]+1 != t[1]), []) >>> iranges = iter(nums[0:1] + ranges + nums[-1:]) >>> print ', '.join([str(n) + '-' + str(next(iranges)) for n in iranges]) 1-5, 7-9, 12-12, 15-18 

这里是另一个没有使用任何模块的基本解决scheme,这对采访是很有好处的,一般在面试时他们不用任何模块就问:

 #!/usr/bin/python def split_list(n): """will return the list index""" return [(x+1) for x,y in zip(n, n[1:]) if yx != 1] def get_sub_list(my_list): """will split the list base on the index""" my_index = split_list(my_list) output = list() prev = 0 for index in my_index: new_list = [ x for x in my_list[prev:] if x < index] output.append(new_list) prev += len(new_list) output.append([ x for x in my_list[prev:]]) return output my_list = [1, 3, 4, 7, 8, 10, 11, 13, 14] print get_sub_list(my_list) 

输出:

 [[1], [3, 4], [7, 8], [10, 11], [13, 14]] 

我有一个类似的问题,并使用以下的sorting列表。 它输出一个字典中列出的值范围的字典。 这些键分隔连续数字的每次运行,并且也是序列之间数字之间的非顺序项目的运行总数。

你的列表给我输出{0: [1, 4], 1: [7, 8], 2: [10, 14]}

 def series_dictf(index_list): from collections import defaultdict series_dict = defaultdict(list) sequence_dict = dict() list_len = len(index_list) series_interrupts = 0 for i in range(list_len): if i == (list_len - 1): break position_a = index_list[i] position_b = index_list[i + 1] if position_b == (position_a + 1): sequence_dict[position_a] = (series_interrupts) sequence_dict[position_b] = (series_interrupts) if position_b != (position_a + 1): series_interrupts += 1 for position, series in sequence_dict.items(): series_dict[series].append(position) for series, position in series_dict.items(): series_dict[series] = [position[0], position[-1]] return series_dict 

使用设置操作,可以执行以下algorithm

 def get_consecutive_integer_series(integer_list): integer_list = sorted(integer_list) start_item = integer_list[0] end_item = integer_list[-1] a = set(integer_list) # Set a b = range(start_item, end_item+1) # Pick items that are not in range. c = set(b) - a # Set operation ba li = [] start = 0 for i in sorted(c): end = b.index(i) # Get end point of the list slicing li.append(b[start:end]) # Slice list using values start = end + 1 # Increment the start point for next slicing li.append(b[start:]) # Add the last series for sliced_list in li: if not sliced_list: # list is empty continue if len(sliced_list) == 1: # If only one item found in list yield sliced_list[0] else: yield "{0}-{1}".format(sliced_list[0], sliced_list[-1]) a = [1, 2, 3, 6, 7, 8, 4, 14, 15, 21] for series in get_consecutive_integer_series(a): print series 

上述列表的输出“a”
1-4
6-8
14-15
21

您可以使用具有名为Counter的类的集合库。 计数器可以派上用场,如果试图在任何迭代中轮询不同的元素

 from collections import Counter data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] cnt=Counter(data) print(cnt) 

这个输出看起来像

 Counter({1: 1, 4: 1, 5: 1, 6: 1, 10: 1, 15: 1, 16: 1, 17: 1, 18: 1, 22: 1, 25: 1, 26: 1, 27: 1, 28: 1}) 

就像任何其他字典可以轮询关键值