Search code examples
pythonlistgrouping

Identify groups of consecutive numbers in a list


I'd like to identify groups of consecutive numbers in a list, so that:

myfunc([2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20])

Returns:

[(2,5), (12,17), 20]

And was wondering what the best way to do this was (particularly if there's something inbuilt into Python).

Edit: Note I originally forgot to mention that individual numbers should be returned as individual numbers, not ranges.


Solution

  • more_itertools.consecutive_groups was added in version 4.0.

    Demo

    import more_itertools as mit
    
    
    iterable = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20]
    [list(group) for group in mit.consecutive_groups(iterable)]
    # [[2, 3, 4, 5], [12, 13, 14, 15, 16, 17], [20]]
    

    Code

    Applying this tool, we make a generator function that finds ranges of consecutive numbers.

    def find_ranges(iterable):
        """Yield range of consecutive numbers."""
        for group in mit.consecutive_groups(iterable):
            group = list(group)
            if len(group) == 1:
                yield group[0]
            else:
                yield group[0], group[-1]
    
    
    iterable = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20]
    list(find_ranges(iterable))
    # [(2, 5), (12, 17), 20]
    

    The source implementation emulates a classic recipe (as demonstrated by @Nadia Alramli).

    Note: more_itertools is a third-party package installable via pip install more_itertools.