Given a list of strings, I want to sort it alphabetically and remove duplicates. I know I can do this:
from sets import Set
[...]
myHash = Set(myList)
but I don't know how to retrieve the list members from the hash in alphabetical order.
I'm not married to the hash, so any way to accomplish this will work. Also, performance is not an issue, so I'd prefer a solution that is expressed in code clearly to a fast but more opaque one.
-
Also see here for more informationuser1129682– user11296822014年03月14日 17:37:49 +00:00Commented Mar 14, 2014 at 17:37
-
1This question, after @ColonelPanic's edit, is kind of a mess; the question in the title and the question in the body are not the same. The title indicates that the original order, pre-duplicate-removal, should be preserved. But the body presents a scenario where this is not in fact necessary.Mark Amery– Mark Amery2019年09月29日 14:05:19 +00:00Commented Sep 29, 2019 at 14:05
-
I changed the title to match the body and the accepted answer.Vladimir Panteleev– Vladimir Panteleev2022年05月03日 07:55:18 +00:00Commented May 3, 2022 at 7:55
6 Answers 6
A list can be sorted and deduplicated using built-in functions:
myList = sorted(set(myList))
-
19This does not work if your myList has unhashable objects.J_Zar– J_Zar2012年11月14日 11:30:04 +00:00Commented Nov 14, 2012 at 11:30
-
wouldn't set(sorted(myList)) be faster? I mean isn't it faster to first sort a list and then remove its duplicates than first removing its duplicates and only sort it afterwards?Zuzu Corneliu– Zuzu Corneliu2017年01月26日 19:27:35 +00:00Commented Jan 26, 2017 at 19:27
-
1@CorneliuZuzu Removing duplicates with set() changes order, so you have to do it this wayDimali– Dimali2017年06月13日 09:25:41 +00:00Commented Jun 13, 2017 at 9:25
-
2Downvoted because there is a distinction between ordered and sorted. Ordered means keep the original order, e.g. f([3,1,4,1,5,9,2,6,5,3,5]) = [3,1,4,5,9,2,6]Ken Seehart– Ken Seehart2019年12月19日 03:38:56 +00:00Commented Dec 19, 2019 at 3:38
-
1@user3667349 The "keep order" clause was not a part of the original question, it was added by the Colonel Panic edit in 2015.Rod Daunoravicius– Rod Daunoravicius2019年12月24日 17:18:11 +00:00Commented Dec 24, 2019 at 17:18
If your input is already sorted, then there may be a simpler way to do it:
from operator import itemgetter
from itertools import groupby
unique_list = list(map(itemgetter(0), groupby(yourList)))
-
5This can also be expressed as [e for e, _ in groupby(sortedList)]Rafał Dowgird– Rafał Dowgird2009年01月26日 15:25:43 +00:00Commented Jan 26, 2009 at 15:25
-
This is O(n) rather than O(n log n) right?Colonel Panic– Colonel Panic2015年10月19日 14:55:29 +00:00Commented Oct 19, 2015 at 14:55
-
FWIW something similar was added to the list of recipes from the documentation for
itertools
.Cristian Ciupitu– Cristian Ciupitu2016年02月16日 10:58:01 +00:00Commented Feb 16, 2016 at 10:58
If you want to keep order of the original list, just use OrderedDict with None
as values.
In Python2:
from collections import OrderedDict
from itertools import izip, repeat
unique_list = list(OrderedDict(izip(my_list, repeat(None))))
In Python3 it's even simpler:
from collections import OrderedDict
from itertools import repeat
unique_list = list(OrderedDict(zip(my_list, repeat(None))))
If you don't like iterators (zip and repeat) you can use a generator (works both in 2 & 3):
from collections import OrderedDict
unique_list = list(OrderedDict((element, None) for element in my_list))
If it's clarity you're after, rather than speed, I think this is very clear:
def sortAndUniq(input):
output = []
for x in input:
if x not in output:
output.append(x)
output.sort()
return output
It's O(n^2) though, with the repeated use of not in for each element of the input list.
> but I don't know how to retrieve the list members from the hash in alphabetical order.
Not really your main question, but for future reference Rod's answer using sorted
can be used for traversing a dict
's keys in sorted order:
for key in sorted(my_dict.keys()):
print key, my_dict[key]
...
and also because tuple
's are ordered by the first member of the tuple, you can do the same with items
:
for key, val in sorted(my_dict.items()):
print key, val
...
For the string data
output = []
def uniq(input):
if input not in output:
output.append(input)
print output