Finding groups of increasing numbers in a list

前端 未结 8 2133
生来不讨喜
生来不讨喜 2021-01-05 03:37

The aim is to find groups of increasing/monotonic numbers given a list of integers. Each item in the resulting group must be of a +1 increment from the previous item

8条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-05 04:07

    If two consecutive numbers are increasing by one I form a list (group) of tuples of those numbers.

    When non-increasing and if the list (group) is non-empty, I unpack it and zip again to rebuild the pair of sequence which were broken by the zip. I use set comprehension to eliminate duplicate numbers.

      def extract_increasing_groups(seq):
        seq = tuple(seq)
    
        def is_increasing(a,b):
            return a + 1 == b
    
        def unzip(seq):
            return tuple(sorted({ y for x in zip(*seq) for y in x}))
    
        group = []
        for a,b in zip(seq[:-1],seq[1:]):
            if is_increasing(a,b):
                group.append((a,b))
            elif group:
                yield unzip(group)
                group = []
    
        if group:
            yield unzip(group)
    
    if __name__ == '__main__':
    
        x = [17, 17, 19, 20, 21, 22, 0, 1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12,
    
             13, 14, 14, 14, 28, 29, 30, 31, 32, 33, 34, 35, 36, 40]
    
        for group in extract_increasing_groups(x):
            print(group)
    

    Simpler one using set;

    from collections import namedtuple
    from itertools import islice, tee
    
    def extract_increasing_groups(iterable):
    
        iter1, iter2 = tee(iterable)
        iter2 = islice(iter2,1,None)
    
        is_increasing = lambda a,b: a + 1 == b
        Igroup = namedtuple('Igroup','group, len')
    
        group = set()
        for pair in zip(iter1, iter2):
            if is_increasing(*pair):
                group.update(pair)
            elif group:
                yield Igroup(tuple(sorted(group)),len(group))
                group = set()
    
        if group:
            yield Igroup(tuple(sorted(group)), len(group))
    
    
    if __name__ == '__main__':
    
        x = [17, 17, 19, 20, 21, 22, 0, 1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 28, 29, 30, 31, 32, 33, 34, 35, 36, 40]
        total = 0
        for group in extract_increasing_groups(x):
            total += group.len
            print('Group: {}\nLength: {}'.format(group.group, group.len))
        print('Total: {}'.format(total))
    

提交回复
热议问题