views:

3287

answers:

3

Is there a built-in that removes duplicates from list in Python, whilst preserving order? I know that I can use a set to remove duplicates, but that destroys the original order. I also know that I can roll my own like this:

def uniq(input):
  output = []
  for x in input:
    if x not in output:
      output.append(x)
  return output

(Thanks to unwind for that code sample.)

But I'd like to avail myself of a built-in or a more Pythonic idiom if possible.

Related question: In Python, what is the fastest algorithm for removing duplicates from a list so that all elements are unique while preserving order?

+12  A: 

Here you have some alternatives: http://www.peterbe.com/plog/uniqifiers-benchmark

Fastest one:

def f7(seq):
    seen = set()
    seen_add = seen.add
    return [ x for x in seq if x not in seen and not seen_add(x)]


EDIT:

If you plan on using this function a lot, perhaps you would be better off with an ordered set: http://code.activestate.com/recipes/528878/

O(1) insertion, deletion and member-check.

MizardX
Thanks for the link! After looking over the functions, I chose f2() for clarity. I should have stated that performance was not an issue.
jmglov
f7 itself is obviously at least O(n), though each insertion, deletion and member-check is individually O(1) (with some definite hashing overhead!). You may want to mention that for some people who are less comfortable with runtime analysis.
llimllib
oh! you mean the ordered set is... nevermind I can't read.
llimllib
+2  A: 
from itertools import groupby
[ key for key,_ in groupby(sortedList)]

The list doesn't even have to be sorted, the sufficient condition is that equal values are grouped together.

Edit: I assumed that "preserving order" implies that the list is actually ordered. If this is not the case, then the solution from MizardX is the right one.

Rafał Dowgird
But this doesn't preserve order!
unbeknown
Hrm, this is problematic, since I cannot guarantee that equal values are grouped together without looping once over the list, by which time I could have pruned the duplicates.
jmglov
I assumed that "preserving order" implied that the list is actually ordered.
Rafał Dowgird
Ah, yes, I read sortedList as sorted(List) :-( But the input list can be in a different order.
unbeknown
Added clarification.
Rafał Dowgird
Maybe the specification of the input list is a little bit unclear. The values don't even need to be grouped together: [2, 1, 3, 1]. So which values to keep and which to delete?
unbeknown
I think that the question should be reattached as a coment under the original question.
Rafał Dowgird
A: 
for i in range(len(theArray)-1,-1,-1): #get the indexes in reverse
 if theArray.count(theArray[i]) > 1:
   theArray.pop(i)
Lulamile