Это на самом деле продолжение этого вопроса. Ответы на этот вопрос не сохранили «порядок» в списке после удаления дубликатов. Как удалить эти дубликаты в списке (python)
biglist = [ {'title':'U2 Band','link':'u2.com'}, {'title':'Live Concert by U2','link':'u2.com'}, {'title':'ABC Station','link':'abc.com'} ]
В этом случае второй элемент следует удалить, поскольку предыдущий элемент u2.com уже существует. Однако порядок следует сохранить.
используйте set (), затем выполните повторную сортировку, используя индекс исходного списка.
>>> mylist = ['c','a','a','b','a','b','c'] >>> sorted(set(mylist), key=lambda x: mylist.index(x)) ['c', 'a', 'b']
Мой ответ на другой ваш вопрос, который вы полностью проигнорировали !, показывает, что вы ошибаетесь, утверждая, что
Ответы на этот вопрос не держать "заказ"
Вероятно, самый быстрый подход для действительно большого списка, , если вы хотите сохранить точный порядок элементов, которые остаются , заключается в следующем ...:
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
Генераторы отличные.
def unique( seq ): seen = set() for item in seq: if item not in seen: seen.add( item ) yield item biglist[:] = unique( biglist )
На этой странице обсуждаются различные методы и их скорости: 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'])
* на этой странице
Это элегантный и компактный способ с пониманием списка (но не такой эффективный, как со словарем):
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]) ]
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
вывод будет:
['ааа', 'аба', 'ааа', 'ааа', 'баа', 'ааа', 'ааа', 'ааа']
['ааа', 'аба', 'аеа', 'баа', 'ааа']
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 гораздо более эффективным, чем использование списка.
not in dups
Я думаю, что использование набора должно быть довольно эффективным.
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))
Супер простой способ сделать это:
def uniq(a): if len(a) == 0: return [] else: return [a[0]] + uniq([x for x in a if x != a[0]])
Это не самый эффективный способ, потому что:
Однако для простого использования (не более нескольких сотен предметов, не критично к производительности) этого достаточно.