3

For example if I have a list as follows:

[3, 3, 3, 3, 3, 3, 100, 1, 1, 1, 1, 1, 1, 200, 3, 3, 3, 100, 1, 1, 1]

How can I remove the duplicate elements and represent the same element followed by the number of times it's repeating? Example Output:

[3, 6, 100, 1, 6, 200, 3, 3, 100, 1, 3]

Where 3 is repeating 6 times... 1 repeating 6 times... and so on

1
  • 3
    [3,2] and [3,3,3] map to same thing, does that raise a potential issue? Commented Feb 22, 2015 at 18:26

4 Answers 4

7

You can use itertools.groupby with a generator function here:

>>> from itertools import groupby                                              
>>> lst = [3, 3, 3, 3, 3, 3, 100, 1, 1, 1, 1, 1, 1, 200, 3, 3, 3, 100, 1, 1, 1]
>>> def solve(seq):
    for k, g in groupby(seq):
        length = sum(1 for _ in g)
        if length > 1:
            yield k
            yield length
        else:
            yield  k
...             
>>> list(solve(lst))
[3, 6, 100, 1, 6, 200, 3, 3, 100, 1, 3]
Sign up to request clarification or add additional context in comments.

Comments

0

The itertools is the best solution but for a different take without imports we can use a dict:

od = {}

prev = None
out = []
for ele in l:
    if ele != prev and prev in od:
        out.extend((prev, od[prev])) if od[prev] > 1 else out.append(prev)
        od[prev] = 0
    od.setdefault(ele, 0)
    od[ele] += 1
    prev = ele
out.extend((ele, od[ele])) if od[ele] > 1 else out.append(ele)
print(out)
[3, 6, 100, 1, 6, 200, 3, 3, 100, 1, 3]

Or in a function using a more efficient defaultdict,it takes more memory to store data in a dict but it is probably a faster solution that using groupby:

def grp1(l):
    od = defaultdict(int)
    prev = None
    out = []
    for ele in l:
        if ele != prev and prev in od:
            out.extend((prev, od[prev])) if od[prev] > 1 else out.append(prev)
            od[prev] = 0
        od[ele] += 1
        prev = ele
    out.extend((ele, od[ele])) if od[ele] > 1 else out.append(ele)
    return out
[3, 6, 100, 1, 6, 200, 3, 3, 100, 1, 3]

Interestingly it is a nice amount faster, probably because we don't have to loop over every sublist to get the len :

In [33]: l = [choice(l) for _ in range(100000)]

In [34]: timeit grp1(l)
10 loops, best of 3: 23.9 ms per loop

In [35]: timeit list(solve(l))
10 loops, best of 3: 33.9 ms per loop

In [36]: list(solve(l)) == grp1(l)
Out[36]: True

Comments

-1

Alternative solution without using itertools would be:

my_list = [3, 3, 3, 3, 3, 3, 100, 1, 1, 1, 1, 1, 1, 200, 3, 3, 3, 100, 1, 1, 1]
new_list = []

new_list.append(my_list[0]) #adding first element

count = 1 #variable for counting repeated elements
i = 1 #iterator through list

l = len(my_list)

while i < l:
    while i < l and my_list[i] == my_list[i-1]:
        count +=1
        i+=1
    if count > 1:
        new_list.append(count)
        count = 1 #returning to original default value
    else:
        new_list.append(my_list[i])
        i+=1

print(new_list)

Comments

-1

As an alternative answer you can just play with indices using a recursion function and iter :

def refiner(li,new=[]):
     it=iter(li[1:])
     for i,j in enumerate(li[:-1],1):
            curr=next(it)
            if j!=curr :
                if i>1:
                  new+=[j,i]
                  return refiner(li[i:],new)

                elif i==len(li)-1:                  
                  new+=[j,curr]
                  return new

                else:
                    new+=[j]
                    return refiner(li[i:],new)

            elif i==len(li)-1:
                  new+=[j,i+1]
                  return new

     return new

DEMO:

l=[3, 3, 3, 3, 3, 3, 100, 1, 1, 1, 1, 1, 1, 200, 3, 3, 3, 100, 1, 1, 1]
print refiner(l)
[3, 6, 100, 1, 6, 200, 3, 3, 100, 1, 3]

l=[7, 7, 3, 9, 3, 3, 100, 1, 5, 1, 1, 1, 1, 200, 3, 3, 3, 100, 1, 7, 1]
print refiner(l)
[7, 2, 3, 9, 3, 2, 100, 1, 5, 1, 4, 200, 3, 3, 100, 1, 7, 1]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.