2

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.

Reti43
  • 9,656
  • 3
  • 28
  • 44
Gabriela
  • 63
  • 5

4 Answers4

4
result = [[x] * A.count(x) for x in set(A) if A.count(x) > 1]
Gamaliel
  • 129
  • 3
  • 8
  • nice! didn't think to use sets so you could do this all inline. you don't really need the conditional at the end, it's prettier without it – Robbie Milejczak Nov 15 '17 at 19:42
2

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]]
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • I appreciate your answer but is not the output I am looking for. For that input the output need to be [[1,1,1,1],[2,2,2], [4,4,4,4]] (not necessary sorted). Just the elements that are repeated in the whole list. – Gabriela Nov 15 '17 at 19:26
  • @Gabriela: simple solution for that. sort your input first - then identical numbers will be grouped by the sort and the algo gives your output (see the algo name for what it does :o) ). – Patrick Artner Nov 15 '17 at 19:27
  • @Gabriela: 2. implementation: Count them up into a dictionary, create list from dict :) output should be ok now – Patrick Artner Nov 15 '17 at 19:49
1

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)

Robbie Milejczak
  • 5,664
  • 3
  • 32
  • 65
1

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]]
Reti43
  • 9,656
  • 3
  • 28
  • 44