Break up list into groups

James Stroud jstroud at mbi.ucla.edu
Tue Jul 17 00:12:53 CEST 2007


danmcleran at yahoo.com wrote:
> All,
> 
> I can't seem to find an answer to this question anywhere, but I'm
> still looking. My problem is I have a list of values like this:
> 
> l = [0xF0, 1, 2, 3, 0xF0, 4, 5, 6, 0xF1, 7, 8, 0xF2, 9, 10, 11, 12,
> 13, 0xF0, 14, 0xF1, 15]
> 
> A value with bit 0x80 set delineates the start of a new packet of
> information. What I want to do is to group the packets so that 1, 2, 3
> go with the 1st packet tagged 0xF0, 4 ,5, 6 go with the 2nd packet
> tagged 0xF0, 7 & 8 go with the packet tagged 0xF1 and so on. The
> length of the data associated with each tag can vary. I've already
> written an algorithm to do this but I was wondering if some
> combination of itertools functions could do the job faster?
> 
> Here's what I've done and the expected output of the algorithm:
> 
> def splitIntoGroups(data):
>     groups = []
>     local = []
> 
>     for value in data:
>         if 0x80 & value:
>             if len(local) > 0:
>                 groups.append(local)
> 
>             local = []
>             local.append(value)
>         else:
>             local.append(value)
> 
>     if len(local) > 0:
>         groups.append(local)
> 
>     return groups
> 
> l = [0xF0, 1, 2, 3, 0xF0, 4, 5, 6, 0xF1, 7, 8, 0xF2, 9, 10, 11, 12,
> 13, 0xF0, 14, 0xF1, 15]
> 
> print splitIntoGroups(l)
> 
> Desired result:
> 
> [[240, 1, 2, 3], [240, 4, 5, 6], [241, 7, 8], [242, 9, 10, 11, 12,
> 13], [240, 14], [241, 15]]
> 
> Thanks,
> 
> Dan McLeran
>

Here's how I *would* do it:

py> def doit(alist):
...   ary = []
...   for i in alist:
...     if 0xf0 & i:
...       ary.append([i])
...     else:
...       ary[-1].append(i)
...   return [x for x in ary if x]
...
py> doit(alist)

[[240, 1, 2, 3],
  [240, 4, 5, 6],
  [241, 7, 8],
  [242, 9, 10, 11, 12, 13],
  [240, 14],
  [241, 15]]


Here's an ugly way I wouldn't recommended (using itertools groupby):

py> from itertools import groupby
py> alist = [0xF0, 1, 2, 3, 0xF0, 4, 5, 6,
...          0xF1, 7, 8, 0xF2, 9, 10, 11, 12, 13,
...          0xF0, 14, 0xF1, 15]
py> def doit(alist):
...   i = (list(g) for k,g in groupby(alist, lambda x: 0xf0&x))
...   return [k for k in [j + i.next() for j in i] if len(k)>1]
...
py> doit(alist)

[[240, 1, 2, 3],
  [240, 4, 5, 6],
  [241, 7, 8],
  [242, 9, 10, 11, 12, 13],
  [240, 14],
  [241, 15]]


James

-- 
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/



More information about the Python-list mailing list