0

I want to split a list sequence of items in Python or group them if they are similar.

I already found a solution but I would like to know if there is a better and more efficient way to do it (always up to learn more).

Here is the main goal

input = ['a','a', 'i', 'e', 'e', 'e', 'i', 'i', 'a', 'a'] 
desired_ouput = [['a','a'], ['i'], ['e','e', 'e'], ['i', 'i'], ['a', 'a']  

So basically I choose to group by similar neighbour.I try to find a way to split them if different but get no success dooing it.

I'm also keen on listening the good way to expose the problem

#!/usr/bin/env python3
def group_seq(listA):
    listA = [[n] for n in listA]
    for i,l in enumerate(listA):
        _curr = l
        _prev = None
        _next= None
        if i+1 < len(listA):
            _next = listA[i+1]
        if i > 0:
            _prev = listA[i-1]    
        if _next is not None and _curr[-1] == _next[0]:
            listA[i].extend(_next)
            listA.pop(i+1)
        if _prev is not None and _curr[0] == _prev[0]:
            listA[i].extend(_prev)
            listA.pop(i-1)
    return listA  
listA = ['a','a', 'i', 'e', 'e', 'e', 'i', 'i', 'a', 'a']
output = group_seq(listA)    
print(listA)
['a', 'a', 'i', 'e', 'e', 'e', 'i', 'i', 'a', 'a']
print(output)   
[['a', 'a'], ['i'], ['e', 'e', 'e'], ['i', 'i'], ['a', 'a']]
c24b
  • 5,278
  • 6
  • 27
  • 35

1 Answers1

2

I think itertool.groupby is probably the nicest way to do this. It's flexible and efficient enough that it's rarely to your advantage to re-implement it yourself:

from itertools import groupby

inp = ['a','a', 'i', 'e', 'e', 'e', 'i', 'i', 'a', 'a'] 

output = [list(g) for k,g in groupby(inp)]
print(output)

prints

[['a', 'a'], ['i'], ['e', 'e', 'e'], ['i', 'i'], ['a', 'a']]

If you do implement it yourself, it can probably be much simpler. Just keep track of the previous value and the current list you're appending to:

def group_seq(listA):
    prev = None
    cur = None
    ret = []

    for l in listA:
        if l == prev:    # assumes list doesn't contain None
            cur.append(l)
        else:
            cur = [l]
            ret.append(cur)
        prev = l

    return ret  
Mark
  • 90,562
  • 7
  • 108
  • 148
  • Waw! I'm feeling dummy because I didn't read the full output of the command and was still stuck on my absolute certitude that it was grouping unique element together! Thanks ! – c24b Jul 07 '19 at 22:31
  • Yeah @c24b it works with iterators taking one item at a time, so it doesn't ever see the whole list — which means it can only work on local groups. – Mark Jul 07 '19 at 22:32
  • 1
    I understand know why when using groupby vast majority speak about sorting it previously! Thanks – c24b Jul 07 '19 at 22:38