-2

This function takes an integer list (which your function must not modify) of unsorted values and returns a sorted list of all the duplicates in that first list. For example, duplicates([1, 3, 5, 7, 9, 5, 3, 5, 3]) would return [3, 5]. If there are no duplicates, return an empty list.

Following is my current code, which doesn't work. How can I solve this problem?

def FindDuplicates(in_list):  
    unique = set(in_list)  
    for each in unique:  
        count = in_list.count(each)  
        if count > 1:  
            print count  
            return True  
    print []  
    return False
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
Aleish
  • 65
  • 5

2 Answers2

1

For doing this without a Counter/dict, you can modify your current code to save the duplicate values in a new list, like below:

def FindDuplicates(in_list):  
    duplicates = []
    unique = set(in_list)
    for each in unique:
        count = in_list.count(each)
        if count > 1:
            duplicates.append(each)
    print duplicates

which will output:

>>> FindDuplicates(lst)
[3, 5]

If you need sorted results, use a sorted(duplicates) call at the end to get results sorted by their values.


You can also solve this (i.e. finding duplicates in a list) using collections.Counter and a list comprehension, as below:

>>> from collections import Counter
>>> lst = [1, 3, 5, 7, 9, 5, 3, 5, 3]
>>> def duplicates(list_of_numbers):
...    counter = Counter(list_of_numbers)
...    return [y for y in counter if counter[y] > 1]
... 
>>> duplicates(lst)
[3, 5]

The above solution assumes the elements of the list are hashable.

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • Are you sure this answers the OPs question? Cause as of right now there isnt one... – heinst Jul 15 '15 at 15:12
  • Thanks a lot, but I used counter before and my teacher said that I'm not allowed to do it. is there any way to do it without counter? – Aleish Jul 15 '15 at 15:13
  • I think you also need a call to `sorted` because counters are arbitrary-order? – NightShadeQueen Jul 15 '15 at 15:14
  • @NightShadeQueen No, order won't be necessarily restored if `sorted` is used. The dicts do not maintain order of keys, and there is no guarantee original list is sorted. – Anshul Goyal Jul 15 '15 at 15:17
  • @Aleish Check edits.., I have edited your current code. This is an unoptimal solution O(N^2), but am not sure if you are allowed to use `dict`s either. – Anshul Goyal Jul 15 '15 at 15:18
  • @heinst I'm hoping it does answer the question now :) – Anshul Goyal Jul 15 '15 at 15:19
1

Slightly faster, at O(nlogn) worst-case

def FindDuplicates(in_list):  
    unique = set()
    duplicates = set()
    for i in in_list:
        if i in unique: #hey, I've seen you before
            duplicates.add(i)
        else:
            unique.add(i)
    return sorted(duplicates) 
    #It's this call to sorted that makes it O(nlogn)
    #without it, it'd be O(n)

Also the "Man, you can't stop me from using a counter!" variant. Also O(nlogn).

def FindDuplicates(in_list):
    d = {}
    for i in in_list:
        if i in d:
            d[i] += 1
        else:
            d[i] = 1
    return sorted(i for i,j in d.items() if j > 1)
   #python2 use d.iteritems() not d.items()

(I suppose

if i not in d:
    d[i] = 1
else:
    d[i] += 1

makes more sense to most people, and it'd work too.)

NightShadeQueen
  • 3,284
  • 3
  • 24
  • 37