Identify groups of varying continuous numbers in a list

前端 未结 4 838
囚心锁ツ
囚心锁ツ 2020-12-17 20:56

In this other SO post, a Python user asked how to group continuous numbers such that any sequences could just be represented by its start/end and any stragglers would be dis

4条回答
  •  一生所求
    2020-12-17 21:57

    You can create an iterator to help grouping and try to pull the next element from the following group which will be the end of the previous group:

    def ranges(lst):
        it = iter(lst)
        next(it)  # move to second element for comparison
        grps = groupby(lst, key=lambda x: (x - next(it, -float("inf"))))
        for k, v in grps:
            i = next(v)
            try:
                step = next(v) - i  # catches single element v or gives us a step
                nxt = list(next(grps)[1])
                yield xrange(i, nxt.pop(0), step)
                # outliers or another group
                if nxt:
                    yield nxt[0] if len(nxt) == 1 else xrange(nxt[0], next(next(grps)[1]), nxt[1] - nxt[0])
            except StopIteration:
                yield i  # no seq
    

    which give you:

    In [2]: l1 = [2, 3, 4, 5, 8, 10, 12, 14, 13, 14, 15, 16, 17, 20, 21]
    
    In [3]: l2 = [2, 4, 6, 8, 12, 13, 14, 15, 16, 17, 20]
    
    In [4]: l3 = [13, 14, 15, 16, 17, 18]
    
    In [5]: s1 = [i + 10 for i in xrange(0, 11, 2)]
    
    In [6]: s2 = [30]
    
    In [7]: s3 = [i + 40 for i in xrange(45)]
    
    In [8]: l4 = s1 + s2 + s3
    
    In [9]: l5 = [1, 2, 5, 6, 9, 10]
    
    In [10]: l6 = {1, 2, 3, 5, 6, 9, 10, 13, 19, 21, 22, 23, 24}
    
    In [11]: 
    
    In [11]: for l in (l1, l2, l3, l4, l5, l6):
       ....:         print(list(ranges(l)))
       ....:     
    [xrange(2, 5), xrange(8, 14, 2), xrange(13, 17), 20, 21]
    [xrange(2, 8, 2), xrange(12, 17), 20]
    [xrange(13, 18)]
    [xrange(10, 20, 2), 30, xrange(40, 84)]
    [1, 2, 5, 6, 9, 10]
    [xrange(1, 3), 5, 6, 9, 10, 13, 19, xrange(21, 24)]
    

    When the step is 1 it is not included in the xrange output.

提交回复
热议问题