Home > Back-end >  how to check and rearrange Python's list which contains a series of incremental values [duplica
how to check and rearrange Python's list which contains a series of incremental values [duplica

Time:09-17

I am just wondering how the list could be rearranged into list of list with a series of incremental integers as list element. For example, let's imagine that I have a list as follows:

example = [2, 43, 44, 64, 143, 144, 145, 146, 147, 148, 178, 179, 180, 181, 182, 183, 184, 211]

And I would like to convert this list into the one as follows:

converted_example = [[2], [43, 44], [64], [143, 144, 145, 146, 147, 148], [178, 179, 180, 181, 182, 183, 184], [211]]

Do you have any ideas on this? Thanks in advance!

CodePudding user response:

import itertools


def groupby_adjacent(max_step_size=1):
    # generate a persistent function that tracks successive calls, 
    # to feed to itertools.groupby
    # (assume the input is already sorted)
    v = {
        'last': None,   # last value encountered
        'group': 0      # value to return for groupby
    }
    def f(current):
        # if the current element exceeds the last element by more than one,
        # break the groupby and start a new group
        if v['last'] is not None and current - max_step_size > v['last']:
            v['group'] = v['group']   1
        # otherwise, just keep the same group as we currently have
        v['last'] = current
        return v['group']
    return f

example = [2, 43, 44, 64, 143, 144, 145, 146, 147, 148, 178, 179, 180, 181, 182, 183, 184, 211]

converted_example = [list(tup[1]) for tup in 
                         itertools.groupby(sorted(example), key=groupby_adjacent())
                    ]
# [[2], [43, 44], [64], [143, 144, 145, 146, 147, 148], [178, 179, 180, 181, 182, 183, 184], [211]]

Each call of groupby_adjacent() will produce a new version of f with its own set of unique local variables, and the returned f can then be passed to a single .groupby() function. I used a dict to store variables instead of actually using variables because I wanted to avoid using the global keyword (it can have behavior reaching beyond where you might intend it to).

The call to sorted() can, of course, be omitted if you can guarantee that example will already be sorted.

  • Related