Подтвердить что ты не робот

Удаление элементов, которые имеют последовательные дубликаты

Я был заинтересован в вопросе: Устранить последовательные дубликаты элементов списка и как его реализовать на 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, есть ли у вас более умный/более элегантный/более эффективный способ реализовать это?

4b9b3361

Ответ 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]