2

I faced some problem with solving the next problem:

We have a list of elements (integers), and we should return a list consisting of only the non-unique elements in this list. Without changing order of the list I think the best way is to delete or remove all unique element.

Take note that I just start to learn python and would like only the simplest solutions.

Here is my code:

def checkio(data):
    for i in data:
        if data.count(i) == 1:    #if element seen in the list just ones, we delet this el
            ind = data.index(i)
            del data[ind]
    return data
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nikolay
  • 80
  • 1
  • 2
  • 9
  • 1
    Rather than deleting the items, what about creating a new list with the unique values? – JoErNanO Nov 11 '14 at 17:26
  • 1
    @JoErNanO I need a list with NON-unique elements (all of them with original order) – Nikolay Nov 11 '14 at 18:44
  • just convert a list into set by using a set() function, you will get the desired output. If you want a final answer in a list, just convert that set into a list using list() function. – Kshitij Labhasetwar Jan 21 '20 at 10:37

9 Answers9

5

You can implement a OrderedCounter, eg:

from collections import OrderedDict, Counter

class OrderedCounter(Counter, OrderedDict): 
    pass

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

duplicates = [k for k, v in OrderedCounter(data).items() if v > 1]
# [1, 3, 2, 5]

So you count the occurrence of each value, then filter on if it has a frequency of more than one. Inheriting from OrderedDict means the order of the original elements is preserved.


Going by comments, you want all duplicated elements reserved, so you can pre-build a set of the duplicate entries, then re-iterate your original list, eg:

from collections import Counter

data = [1, 3, 1, 2, 3, 5, 8, 1, 5, 2]
duplicates = {k for k, v in Counter(data).items() if v > 1}
result = [el for el in data if el in duplicates]
# [1, 3, 1, 2, 3, 5, 1, 5, 2]
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • The first one looks like wishful thinking. Inherit from two classes, hoping that the result does what you want it to. Maybe it does, but it's not obvious why. – Kelly Bundy Apr 01 '23 at 21:35
5

Your function can be made to work by iterating over the list in reverse:

def checkio(data):
    for index in range(len(data) - 1, -1, -1):
        if data.count(data[index]) == 1:
            del data[index]
    return data

print(checkio([3, 3, 5, 8, 1, 4, 5, 2, 4, 4, 3, 0]))
[3, 3, 5, 4, 5, 4, 4, 3]
print(checkio([1, 2, 3, 4]))
[]

This works, because it only deletes numbers in the section of the list that has already been iterated over.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • This has a quadratic run time complexity. The better (`O(n)`) solution is to [use a `Counter`](https://stackoverflow.com/a/26870897/1222951). – Aran-Fey Mar 31 '18 at 15:47
5

Just I used list Comprehensions.

def checkio(data):
    a=[i for i in data if data.count(i)>1]
    return a
print checkio([1,1,2,2,1,1,1,3,4,5,6,7,8]) 
Satish Kumar Reddy
  • 111
  • 1
  • 2
  • 5
2

Try this:

>>> a=[1,2,3,3,4,5,6,6,7,8,9,2,0,0]
>>> a=[i for i in a if a.count(i)>1]
>>> a
[2, 3, 3, 6, 6, 2, 0, 0]
>>> a=[1, 2, 3, 1, 3]
>>> a=[i for i in a if a.count(i)>1]
>>> a
[1, 3, 1, 3]
>>> a=[1, 2, 3, 4, 5]
>>> a=[i for i in a if a.count(i)>1]
a
[]
Irshad Bhat
  • 8,479
  • 1
  • 26
  • 36
  • i ned all of non-unique elements. Example 1: [1, 2, 3, 1, 3] -->> 1 and 3 non-unique elements and result will be [1, 3, 1, 3]. Example 2: [1, 2, 3, 4, 5] -->> non unique elements and result will be [] – Nikolay Nov 11 '14 at 18:47
2
def checkio(data):
    lis = []
    for i in data:
        if data.count(i)>1:
            lis.append(i)
    print(lis)
checkio([1,2,3,3,2,1])

Yeah it's a bit late to contribute to this thread but just wanted to put it there on the net for anyone else use.

Max
  • 23
  • 2
1

Following what you have started, iterating on the list of integers, but not counting or deleting elements, try just testing if the element has already been seen, append it to a list of duplicated elements:

def checkio(data):
    elements = []
    duplicates = []
    for i in data:
        if i not in elements:
            elements.append(i)
        else:
            if i not in duplicates:
                duplicates.append(i)
    return duplicates

d = [1, 3, 1, 2, 3, 5, 8, 1, 5, 2]

print (checkio(d))
#[1, 3, 5, 2]
chapelo
  • 2,519
  • 13
  • 19
  • d = [1, 3, 1, 2, 3, 5, 8, 1, 5, 2] result should be --->>> [1, 3, 1, 2, 3, 5, 1, 5, 2] (deleted onlu unique '8') – Nikolay Nov 11 '14 at 19:07
1
 numbers = [1, 1, 1, 1, 3, 4, 9, 0, 1, 1, 1]
 x=set(numbers)
 print(x)

You can use the set key word too to get the desired solution.

Pole_Star
  • 107
  • 7
0

I used an integer and bool to check every time the list was modified within a while loop.

rechecks = 1
runscan = True
while runscan == True:
    for i in data:
         if data.count(i) <2:
             data.remove(i)
             rechecks+=1
            #need to double check now
    if rechecks >0:
        runscan = True
        rechecks-=1
    else:
        runscan = False       
return data
Kris
  • 1
  • 1
0

Would it not be easier to generate a new list?

def unique_list(lst):
    new_list = []
    for value in lst:
        if value not in new_list:
            new_list.append(value)
    return new_list

lst = [1,2,3,1,4,5,1,6,2,3,7,8,9]
print(unique_list(lst))

Prints [1,2,3,4,5,6,7,8,9]

Jace999
  • 761
  • 1
  • 6
  • 7