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