Удаление элементов, которые имеют последовательные дубликаты
Я был заинтересован в вопросе: Устранить последовательные дубликаты элементов списка и как его реализовать на Python.
Я придумал следующее:
list = [1,1,1,1,1,1,2,3,4,4,5,1,2]
i = 0
while i < len(list)-1:
if list[i] == list[i+1]:
del list[i]
else:
i = i+1
Вывод:
[1, 2, 3, 4, 5, 1, 2]
Я думаю, это нормально.
Итак, мне стало любопытно, и я хотел посмотреть, могу ли я удалить элементы, у которых были последовательные дубликаты и получить этот вывод:
[2, 3, 5, 1, 2]
Для этого я сделал это:
list = [1,1,1,1,1,1,2,3,4,4,5,1,2]
i = 0
dupe = False
while i < len(list)-1:
if list[i] == list[i+1]:
del list[i]
dupe = True
elif dupe:
del list[i]
dupe = False
else:
i += 1
Но это похоже на неуклюжий, а не на pythonic, есть ли у вас более умный/более элегантный/более эффективный способ реализовать это?
Ответы
Ответ 1
>>> L = [1,1,1,1,1,1,2,3,4,4,5,1,2]
>>> from itertools import groupby
>>> [x[0] for x in groupby(L)]
[1, 2, 3, 4, 5, 1, 2]
Если вы хотите, вы можете использовать карту вместо понимания списка
>>> from operator import itemgetter
>>> map(itemgetter(0), groupby(L))
[1, 2, 3, 4, 5, 1, 2]
Для второй части
>>> [x for x, y in groupby(L) if len(list(y)) < 2]
[2, 3, 5, 1, 2]
Если вы не хотите создавать временный список, просто чтобы взять длину, вы можете использовать сумму по выражению генератора
>>> [x for x, y in groupby(L) if sum(1 for i in y) < 2]
[2, 3, 5, 1, 2]
Ответ 2
Oneliner в чистом Python
[v for i, v in enumerate(your_list) if i == 0 or v != your_list[i-1]]
Ответ 3
Вот решение вне зависимости от внешних пакетов:
list = [1,1,1,1,1,1,2,3,4,4,5,1,2]
L = list + [999] # append a unique dummy element to properly handle -1 index
[l for i, l in enumerate(L) if l != L[i - 1]][:-1] # drop the dummy element
Тогда я заметил, что Ульф Аслак похожее решение чище :)
Ответ 4
Устранение последовательных дубликатов элементов списка; в качестве альтернативы вы можете использовать itertools.izip_longest()
с пониманием списка как:
>>> from itertools import izip_longest
>>> my_list = [1,1,1,1,1,1,2,3,4,4,5,1,2]
>>> [i for i, j in izip_longest(my_list, my_list[1:]) if i!=j]
[1, 2, 3, 4, 5, 1, 2]
Ответ 5
Я столкнулся с вашим сообщением, у меня была проблема с его решением, это было близко к вашей, это быстрая попытка, которую я реализовал от использования итераций python, следуя
def superString(s):
sList = list(s)
k=len(sList)-1
j=0
i=0
change=True
while i <= k+1 and change:
change = False
while j< k:
if (sList[j]==sList[j+1]):
sList.pop(j)
sList.pop(j)
k=len(sList)-1
change=True
else:
j+=1
if change == True:
k=len(sList)-1
j=0
else:
k=len(sList)-1
j=0
i+=1
if "".join(sList)!="":
return "".join(sList)
return "Empty String"
s="lrfkqyuqfjjfquyqkfrlkxyqvnrtyssytrnvqyxkfrzrmzlygffgylzmrzrfveulqfpdbhhbdpfqluevlqdqrrcrwddwrcrrqdql"
print superString(s)
Empty String
Ответ 6
Здесь тупой 1-лайнер работает быстрее, чем любое предложение:
→ > l = [1,1,1,1,1,1,2,3,4,4,5,1,2]
→ > [j для i, j в перечислении (l), если нет (i < len (l) -1 и j равно l [i + 1]), а не (i > 0 и j равно l [ I-1])]
[2,3,5,1,2]
или даже проще...
→ > [j для i, j в перечислении (l), если l [i:]. count (j) == 1 и l [: i].count(j) равно 0]
Измените предыдущий '==' на ' > ', и у вас будет список дубликатов.
Или для игнорирования подчиненных...
→ > [i для я в l, если l.count(i) равно 1]