在保持其顺序的同时删除列表中的重复项(Python)

时间:2009-10-11 00:49:35

标签: python list

这实际上是这个问题的延伸。删除重复项后,该问题的答案没有保留列表的“顺序”。 How to remove these duplicates in a list (python)

biglist = 

[ 

    {'title':'U2 Band','link':'u2.com'}, 
    {'title':'Live Concert by U2','link':'u2.com'},
    {'title':'ABC Station','link':'abc.com'}

]

在这种情况下,应该删除第二个元素,因为先前的“u2.com”元素已经存在。但是,应该保留订单。

9 个答案:

答案 0 :(得分:31)

使用set(),然后使用原始列表的索引重新排序。

>>> mylist = ['c','a','a','b','a','b','c']
>>> sorted(set(mylist), key=lambda x: mylist.index(x))
['c', 'a', 'b']

答案 1 :(得分:23)

我对你完全忽略的另一个问题的回答,显示你声称

是错误的
  

那个问题的答案没有   保持“秩序”

  • 我的回答确实保持秩序,显然确实如此。在这里再次强调,看看你是否可以继续忽略它......:

对于一个非常大的列表,可能是最快的方法,如果你想保留项目的确切顺序,则是以下......:

biglist = [ 
    {'title':'U2 Band','link':'u2.com'}, 
    {'title':'ABC Station','link':'abc.com'}, 
    {'title':'Live Concert by U2','link':'u2.com'} 
]

known_links = set()
newlist = []

for d in biglist:
  link = d['link']
  if link in known_links: continue
  newlist.append(d)
  known_links.add(link)

biglist[:] = newlist

答案 2 :(得分:9)

发电机很棒。

def unique( seq ):
    seen = set()
    for item in seq:
        if item not in seen:
            seen.add( item )
            yield item

biglist[:] = unique( biglist )

答案 3 :(得分:3)

本页讨论了不同的方法及其速度: http://www.peterbe.com/plog/uniqifiers-benchmark

推荐*方法:

def f5(seq, idfun=None):  
    # order preserving 
    if idfun is None: 
        def idfun(x): return x 
    seen = {} 
    result = [] 
    for item in seq: 
        marker = idfun(item) 
        # in old Python versions: 
        # if seen.has_key(marker) 
        # but in new ones: 
        if marker in seen: continue 
        seen[marker] = 1 
        result.append(item) 
    return result

f5(biglist,lambda x: x['link'])

*该页面

答案 4 :(得分:2)

这是一种优雅而紧凑的方式,具有列表理解(但效率不如字典):

mylist = ['aaa','aba','aaa','aea','baa','aaa','aac','aaa',]

[ v for (i,v) in enumerate(mylist) if v not in mylist[0:i] ]

在答案的背景下:

[ v for (i,v) in enumerate(biglist) if v['link'] not in map(lambda d: d['link'], biglist[0:i]) ]

答案 5 :(得分:1)

dups = {}
newlist = []
for x in biglist:
    if x['link'] not in dups:
      newlist.append(x)
      dups[x['link']] = None

print newlist

产生

[{'link': 'u2.com', 'title': 'U2 Band'}, {'link': 'abc.com', 'title': 'ABC Station'}]

请注意,我在这里使用了字典。这使得测试not in dups比使用列表更有效。

答案 6 :(得分:1)

list = ['aaa','aba','aaa','aea','baa','aaa','aac','aaa',]

uniq = []

for i in list:
               if i not in uniq:
                   uniq.append(i)

print list

print uniq

输出将是:

['aaa','aba','aaa','aea','baa','aaa','aac','aaa']

['aaa','aba','aea','baa','aac']

答案 7 :(得分:0)

执行此操作的一种非常简单的方法是:

def uniq(a):
    if len(a) == 0:
        return []
    else:
        return [a[0]] + uniq([x for x in a if x != a[0]])

这不是最有效的方式,因为:

  • 它在整个列表中搜索列表中的每个元素,因此它是O(n ^ 2)
  • 它是递归的,因此使用的堆栈深度等于列表的长度

但是,对于简单的用途(不超过几百项,而不是性能关键)就足够了。

答案 8 :(得分:0)

我认为使用套装应该非常有效。

seen_links = set()
for index in len(biglist):
    link = biglist[index]['link']
    if link in seen_links:
        del(biglist[index])
    seen_links.add(link)

我认为这应该出现在O(nlog(n))