In python, how to group elements together, based on a key (group adjacent)?

Question:

In python, I’d like to group elements together based on a key (in example below, key is second element, or element[1]).

initial_array = [[10, 0], [30, 0], [40, 2], [20, 2], [90, 0], [80, 0]]

Only elements which keys are the same and that are adjacent should be grouped together.

splited_array = [ [[10, 0], [30, 0]], 
                  [[40, 2], [20, 2]], 
                  [[90, 0], [80, 0]] ]

Additionally, i’d like the element that caused the split to be also at the end of the previous array.

splited_array = [ [[10, 0], [30, 0], [40, 2]], 
                  [[40, 2], [20, 2], [90, 0]], 
                  [[90, 0], [80, 0]] ]

What is the easiest way to do that in python ? (re-using Built-in Functions if possible)

Asked By: tigrou

||

Answers:

You can use itertools.groupby:

>>> from itertools import groupby
>>> from operator import itemgetter
>>> lis = [[10, 0], [30, 0], [40, 2], [20, 2], [90, 0], [80, 0]]
>>> [list(g) for k,g in groupby(lis, key=itemgetter(1))]
[[[10, 0], [30, 0]],
 [[40, 2], [20, 2]],
 [[90, 0], [80, 0]]]

For second one:

>>> ans = []
for k,g in groupby(lis, key=itemgetter(1)):
    l = list(g)
    ans.append(l)
    if len(ans) > 1:
        ans[-2].append(l[0])
...         
>>> ans
[[[10, 0], [30, 0], [40, 2]],
 [[40, 2], [20, 2], [90, 0]],
 [[90, 0], [80, 0]]]

Update:

>>> from itertools import zip_longest
>>> lis = [[[10, 0], [30, 0]],
 [[40, 2], [20, 2]],
 [[90, 0], [80, 0]]]
>>> [x + ([y[0]] if y else []) for x,y in 
                                        zip_longest(lis,lis[1:])]
[[[10, 0], [30, 0], [40, 2]],
 [[40, 2], [20, 2], [90, 0]],
 [[90, 0], [80, 0]]]
Answered By: Ashwini Chaudhary
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.