在Python 2.2中去重并排序列表

6 投票
4 回答
5086 浏览
提问于 2025-04-17 04:20

在Python 2.2(别问为什么用这个版本),有没有什么简单的方法可以对一个列表进行排序并去掉重复的元素呢?

我当然可以写一个函数,先用sort()进行排序,然后再遍历一遍,但我在想有没有一种更简洁的一行代码的写法。

补充:这个列表很短,所以效率不是问题。而且,列表里的元素是不可变的。

4 个回答

2

需要说明的是,Python 2.2 确实有集合(sets),不过它是在一个叫“sets”的模块里,所以你可以通过这个模块来使用集合,这样你就能做很多事情了:

from sets import Set
myList = list(Set(myList))
# now we're duplicate-free, a standard sorting might be enough
myList.sort()
5

地道的写法 并且 一行代码?不可能。

这里有个不地道、丑得要命的一行代码。

>>> x = [4, 3, 3, 2, 4, 1]
>>> [y for y in (locals().__setitem__('d',{}) or x.sort() or x) 
        if y not in d and (d.__setitem__(y, None) or True)]
[1, 2, 3, 4]

如果接受简单的两行代码:

x = [4, 3, 3, 2, 4, 1]
x = dict(map(None,x,[])).keys()
x.sort()

或者可以写两个小的辅助函数(适用于任何序列):

def unique(it):
    return dict(map(None,it,[])).keys()

def sorted(it):
    alist = [item for item in it]
    alist.sort()
    return alist

print sorted(unique([4, 3, 3, 2, 4, 1]))

结果是

[1, 2, 3, 4]

最后,这是一种半地道的一行代码:

x = [4, 3, 3, 2, 4, 1]
x.sort() or [s for s, t in zip(x, x[1:] + [None]) if s != t]
7

对于旧版本的Python,由于你在使用字符串,我想不出有什么简单的一行代码可以解决这个问题,但可以考虑使用字典来实现,模式大概是这样的:

def sorted_uniq(your_list):
    table = {}
    for s in your_list:
        table[s] = None
    k = table.keys()
    k.sort()
    return k

这个方法是从一个古老的ActiveState代码片段讨论中改编而来的,Alex Martelli本人在这个讨论中也写了几条评论:http://code.activestate.com/recipes/52560/

还有一种更简洁的方法,可以用列表推导式来实现:

def sort_uniq(alist):
   d = {}
   mod_list = [d.setdefault(i,i) for i in alist if i not in d]
   mod_list.sort()
   return mod_list

除了Steven提供的那个简洁(但稍微不太好看的)一行代码,我认为这是一种用Python 2.2实现的最少行数和最符合习惯的方式:

感谢评论中的Steven Rumbalski,第二个版本可以通过Python的zip函数进一步简化:

def sort_uniq(alist):
   mod_list = dict(zip(alist,alist)).keys()
   mod_list.sort()
   return mod_list

如果list.sort()不是通过副作用来操作的话,我们就可以用一行代码解决了。;)

撰写回答