Gabriela
Gabriela

Reputation: 63

Group repeated elements of a list

I am trying to create a function that receives a list and return another list with the repeated elements.

For example for the input A = [2,2,1,1,3,2] (the list is not sorted) and the function would return result = [[1,1], [2,2,2]]. The result doesn't need to be sorted.

I already did it in Wolfram Mathematica but now I have to translate it to python3, Mathematica has some functions like Select, Map and Split that makes it very simple without using long loops with a lot of instructions.

Upvotes: 2

Views: 959

Answers (4)

Reti43
Reti43

Reputation: 9796

This is a job for Counter(). Iterating over each element, x, and checking A.count(x) has a O(N^2) complexity. Counter() will count how many times each element exists in your iterable in one pass and then you can generate your result by iterating over that dictionary.

>>> from collections import Counter
>>> A = [2,2,1,1,3,2]
>>> counts = Counter(A)
>>> result = [[key] * value for key, value in counts.items() if value > 1]
>>> result
[[2, 2, 2], [[1, 1]]

Upvotes: 1

Patrick Artner
Patrick Artner

Reputation: 51643

Simple approach:

def grpBySameConsecutiveItem(l):
    rv= []
    last = None
    for elem in l:
        if last == None:
            last = [elem]
            continue
        if elem == last[0]:
            last.append(elem)
            continue
        if len(last) > 1:
            rv.append(last)
        last = [elem]
    return rv


print grpBySameConsecutiveItem([1,2,1,1,1,2,2,3,4,4,4,4,5,4])

Output:

[[1, 1, 1], [2, 2], [4, 4, 4, 4]]

You can sort your output afterwards if you want to have it sorted or sort your inputlist , then you wouldnt get consecutive identical numbers any longer though.

See this https://stackoverflow.com/a/4174955/7505395 for how to sort lists of lists depending on an index (just use 0) as all your inner lists are identical.

You could also use itertools - it hast things like TakeWhile - that looks much smarter if used

This will ignore consecutive ones, and just collect them all:

def grpByValue(lis):
    d = {}
    for key in lis:
        if key in d:
            d[key] += 1
        else:
            d[key] = 1
    print(d)    

    rv = []
    for k in d:
        if (d[k]<2): 
            continue
        rv.append([])
        for n in range(0,d[k]):
            rv[-1].append(k)
    return rv



data = [1,2,1,1,1,2,2,3,4,4,4,4,5,4]

print grpByValue(data) 

Output:

[[1, 1, 1, 1], [2, 2, 2], [4, 4, 4, 4, 4]]

Upvotes: 2

Gamaliel
Gamaliel

Reputation: 129

result = [[x] * A.count(x) for x in set(A) if A.count(x) > 1]

Upvotes: 4

Robbie Milejczak
Robbie Milejczak

Reputation: 5770

You could do this with a list comprehension:

A = [1,1,1,2,2,3,3,3]
B = []
[B.append([n]*A.count(n)) for n in A if B.count([n]*A.count(n)) == 0]

outputs [[1,1,1],[2,2],[3,3,3]]

Or more pythonically:

A = [1,2,2,3,4,1,1,2,2,2,3,3,4,4,4]
B = []
for n in A:
    if B.count([n]*A.count(n)) == 0:
        B.append([n]*A.count(n))

outputs [[1,1,1],[2,2,2,2,2],[3,3,3],[4,4,4,4]]

Works with sorted or unsorted list, if you need to sort the list before hand you can do for n in sorted(A)

Upvotes: 1

Related Questions