Удалить дубликаты в списке, сохраняя его порядок (Python) - PullRequest
20 голосов
/ 11 октября 2009

Это на самом деле продолжение этого вопроса. Ответы на этот вопрос не сохранили «порядок» в списке после удаления дубликатов. Как удалить эти дубликаты в списке (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 ]

32 голосов
/ 29 августа 2014

используйте set (), затем выполните повторную сортировку, используя индекс исходного списка.

>>> mylist = ['c','a','a','b','a','b','c']
>>> sorted(set(mylist), key=lambda x: mylist.index(x))
['c', 'a', 'b']
23 голосов
/ 11 октября 2009

Мой ответ на другой ваш вопрос, который вы полностью проигнорировали !, показывает, что вы ошибаетесь, утверждая, что

Ответы на этот вопрос не держать "заказ"

  • мой ответ сделал следил за порядком, и он ясно сказал он сделал. Здесь снова, с дополнительным акцентом, чтобы увидеть, можете ли вы просто игнорировать это ...:

Вероятно, самый быстрый подход для действительно большого списка, , если вы хотите сохранить точный порядок элементов, которые остаются , заключается в следующем ...:

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
9 голосов
/ 11 октября 2009

Генераторы отличные.

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

biglist[:] = unique( biglist )
3 голосов
/ 11 октября 2009

На этой странице обсуждаются различные методы и их скорости: 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'])

* на этой странице

2 голосов
/ 20 марта 2014

Это элегантный и компактный способ с пониманием списка (но не такой эффективный, как со словарем):

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]) ]
1 голос
/ 05 марта 2012
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

вывод будет:

['ааа', 'аба', 'ааа', 'ааа', 'баа', 'ааа', 'ааа', 'ааа']

['ааа', 'аба', 'аеа', 'баа', 'ааа']

1 голос
/ 11 октября 2009
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 гораздо более эффективным, чем использование списка.

0 голосов
/ 11 октября 2009

Я думаю, что использование набора должно быть довольно эффективным.

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))

0 голосов
/ 11 октября 2009

Супер простой способ сделать это:

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)
  • он рекурсивный, поэтому использует глубину стека, равную длине списка

Однако для простого использования (не более нескольких сотен предметов, не критично к производительности) этого достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...