Chunking sequential values in a list

Gerard Flanagan grflanagan at yahoo.co.uk
Fri Jul 14 07:43:15 EDT 2006


David Hirschfield wrote:
> I have this function:
>
> def sequentialChunks(l, stride=1):
>     chunks = []
>     chunk = []
>     for i,v in enumerate(l[:-1]):
>         v2 = l[i+1]
>         if v2-v == stride:
>             if not chunk:
>                 chunk.append(v)
>             chunk.append(v2)
>         else:
>             if not chunk:
>                 chunk.append(v)
>             chunks.append(chunk)
>             chunk = []
>     if chunk:
>         chunks.append(chunk)
>     return chunks
>
> Which takes a list of numerical values "l" and splits it into chunks
> where each chunk is sequential, where sequential means each value in a
> chunk is
> separated from the next by "stride".
>
> So sequentialChunks([1,2,3,5,6,8,12]) returns:
>
> [[1,2,3],[5,6],[8],[12]]
>
> I don't think the code above is the most efficient way to do this, but
> it is relatively clear. I tried fiddling with list-comprehension ways of
> accomplishing it, but kept losing track of things...so if anyone has a
> suggestion, I'd appreciate it.
>

Gerard wrote:
>see the groupby example here:
>
>    http://docs.python.org/lib/itertools-example.html

tweaking the example from the docs to take the stride into account:

def stride(length):
    i = 0
    while True:
        yield i
        i += length

def group(data,d=1):
    for k, g in groupby(zip(stride(d),data), lambda (i,x):i-x):
        yield map(operator.itemgetter(1), g)

data = [1,2,3, 5, 6, 8, 12,13,14]

print list( group( data,2 ) )

hth

Gerard




More information about the Python-list mailing list