converting a list of integers into range in python

后端 未结 11 1420
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-28 07:35

Is there something existing in python that can convert an increasing list of integers into a range list

E.g. given the set {0, 1, 2, 3, 4, 7, 8, 9, 11} I want to get

11条回答
  •  青春惊慌失措
    2020-11-28 08:03

    You can use a list comprehension with a generator expression and a combination of enumerate() and itertools.groupby():

    >>> import itertools
    >>> l = [0, 1, 2, 3, 4, 7, 8, 9, 11]
    >>> [[t[0][1], t[-1][1]] for t in
    ... (tuple(g[1]) for g in itertools.groupby(enumerate(l), lambda (i, x): i - x))]
    [[0, 4], [7, 9], [11, 11]]
    

    First, enumerate() will build tuples from the list items and their respective index:

    >>> [t for t in enumerate(l)]
    [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 7), (6, 8), (7, 9), (8, 11)]
    

    Then groupby() will group those tuples using the difference between their index and their value (which will be equal for consecutive values):

    >>> [tuple(g[1]) for g in itertools.groupby(enumerate(l), lambda (i, x): i - x)]
    [((0, 0), (1, 1), (2, 2), (3, 3), (4, 4)), ((5, 7), (6, 8), (7, 9)), ((8, 11),)]
    

    From there, we only need to build lists from the values of the first and last tuples of each group (which will be the same if the group only contains one item).

    You can also use [(t[0][1], t[-1][1]) ...] to build a list of range tuples instead of nested lists, or even ((t[0][1], t[-1][1]) ...) to turn the whole expression into a iterable generator that will lazily build the range tuples on the fly.

提交回复
热议问题