在Python 2.2 (请勿询问)中,排序列表并删除重复项的最佳方法是什么?
我显然可以写一个函数sort()
然后迭代,但我想知道是否有惯用的单行。
编辑:列表很短,因此效率不是问题。此外,元素是不可变的。
答案 0 :(得分: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
除了史蒂文的整洁(但略微没有吸引力)的一个班轮,我认为这是朝着最少的线和最惯用的方式使用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()
没有副作用,我们会有一个班轮。 ;)
答案 1 :(得分: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]
答案 2 :(得分:2)
对于记录,Python 2.2 确实有集合,但在“sets”模块下,所以这将为您提供很长的路要走:
from sets import Set
myList = list(Set(myList))
# now we're duplicate-free, a standard sorting might be enough
myList.sort()
答案 3 :(得分:0)
最好的答案可能是使用二叉树:
# Make yield work in Python 2.2
from __future__ import generators
class TreeNode(object):
def __init__(self, value):
self.left = None
self.right = None
self.value = value
def add(self, value):
if value == self.value:
return
if value < self.value:
if self.left is None:
self.left = TreeNode(value)
else:
self.left.add(value)
else:
if self.right is None:
self.right = TreeNode(value)
else:
self.right.add(value)
def __iter__(self):
if self.left is not None:
for value in self.left:
yield value
yield self.value
if self.right is not None:
for value in self.right:
yield value
class DedupeSorter(object):
def __init__(self):
self.root = None
def add(self, value):
if self.root is None:
self.root = TreeNode(value)
else:
self.root.add(value)
def __iter__(self):
if self.root is None:
return []
else:
return self.root.__iter__()
def dedupe_and_sort(l):
sorter = DedupeSorter()
for value in l:
sorter.add(value)
return list(sorter)
绝对不是惯用语,但应该很快。它基本上创建了一个基于树的集合并对其进行迭代。我没有Python 2.2所以希望它有效:p