有序集Python 2.7

问题描述

| 我有一个尝试从中删除重复项的列表。我正在使用python 2.7.1,因此我可以简单地使用set()函数。但是,这重新排列了我的列表。对于我的特殊情况,这是不可接受的。 下面是我编写的函数;做到这一点。但是我想知道是否有更好/更快的方法。此外,对此的任何评论将不胜感激。
    def ordered_set(list_):

        newlist = []
        lastitem = None
        for item in list_:

            if item != lastitem:
                newlist.append(item)
                lastitem = item

        return newlist
上面的函数假定所有项目都不是None,并且项目按顺序排列(即[\'a \',\'a \',\'a \',\'b \',\' b \',\'c \',\'d \']) 上面的函数返回[\'a \',\'a \',\'a \',\'b \',\'b \',\'c \',\'d \']作为[\ 'A B C D\']。     

解决方法

        使用OrderedDict:
from collections import OrderedDict

l = [\'a\',\'a\',\'b\',\'c\',\'d\']
d = OrderedDict()

for x in l:
    d[x] = True

# prints a b c d
for x in d:
    print x,print
    ,        另一个非常快速的set方法:
def remove_duplicates(lst):
    dset = set()
    # relies on the fact that dset.add() always returns None.
    return [item for item in lst
            if item not in dset and not dset.add(item)] 
    ,        假设输入序列是无序的,这里是3解(在空间和时间上)。 它会产生一个序列,其中删除了重复项,同时以与输入序列中出现的相对顺序相同的相对顺序保留了唯一项。
>>> def remove_dups_stable(s):
...   seen = set()
...   for i in s:
...     if i not in seen:
...       yield i
...       seen.add(i)

>>> list(remove_dups_stable([\'q\',\'w\',\'e\',\'r\',\'q\',\'y\',\'u\',\'i\',\'t\',\'p\',\'e\']))
[\'q\',\'p\']
    ,        我知道这已经被回答了,但是这里是一线(加上导入):
from collections import OrderedDict
def dedupe(_list):
    return OrderedDict((item,None) for item in _list).keys()

>>> dedupe([\'q\',\'e\'])
[\'q\',\'p\']
    ,        我认为这完全可以。您将获得O(n)性能,这是您所希望的最佳结果。 如果列表是无序的,那么您将需要一个帮手
set
来包含您已经访问过的物品,但是对于您而言,则没有必要。     ,        如果您的列表未排序,那么您的问题就没有意义。 例如[1,2,1]可能变为[1,2]或[2,1] 如果列表很大,则可能需要使用SLICE将结果写回到同一列表中以节省内存:
>>> x=[\'a\',\'d\']
>>> x[:]=[x[i] for i in range(len(x)) if i==0 or x[i]!=x[i-1]]
>>> x
[\'a\',\'d\']
有关内联删除的信息,请参见在迭代时从列表中删除项目或在迭代时从列表中删除项目,而无需在Python中使用额外的内存 您可以使用的一个技巧是,如果您知道x已排序,并且知道x [i] = x [i + j],则无需检查x [i]和x [i + j]之间的任何内容(如果您不需要删除这些j值,则可以将所需的值复制到新列表中) 因此,如果集合中的所有内容都是唯一的,即您无法击败n次运算,即len(set(x))= len(x) 可能存在一种算法,它的n个比较是最坏的情况,但是可以将n / 2个比较作为它的最佳情况(如果您事先知道len(x)/ len( set(x))> 2,因为您已经生成了数据): 最佳算法可能会使用二分法搜索以分而治之的方式为每个最小值i找到最大值j。初始除法的长度可能为len(x)/近似(len(set(x)))。希望可以这样执行,即使len(x)= len(set(x))仍然只使用n个操作。     ,        在中描述了unique_everseen解决方案 http://docs.python.org/2/library/itertools.html
def unique_everseen(iterable,key=None):
    \"List unique elements,preserving order. Remember all elements ever seen.\"
    # unique_everseen(\'AAAABBBCCDAABBB\') --> A B C D
    # unique_everseen(\'ABBCcAD\',str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in ifilterfalse(seen.__contains__,iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element
    ,        对我来说还不错。如果您真的想使用集合,请执行以下操作:
def ordered_set (_list) :
    result = set()
    lastitem = None
    for item in _list :
        if item != lastitem :
            result.add(item)
            lastitem = item
    return sorted(tuple(result))
我不知道您将获得什么性能,应该进行测试;可能由于方法过热而相同! 如果您真的像我一样偏执,请阅读以下内容: http://wiki.python.org/moin/HowTo/Sorting/ http://wiki.python.org/moin/PythonSpeed/PerformanceTips 只是想起了这个(它包含答案): http://www.peterbe.com/plog/uniqifiers-benchmark     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...