Как отминусовать j

Рейтинг: -2Ответов: 3Опубликовано: 05.04.2023
list=[1,2,2,2,3,3]
for j in range(0,4):
    print(j)
    if list[j]==list[j+1]:
        list.pop(j)
        # j=j-1
print(list)

Нужно чтобы значение j не менялось в случае, если list[j]==list[j+1] так как после удаления элемента из списка все элементы смещаются и индексы соответственно тоже. Подскажите, как это реализовать

Ответы

▲ 3

1

От каждой группы одинаковых элементов нужно оставить одного представителя - itertools.groupby:

import itertools


list_1 = [1, 2, 2, 2, 3, 3]
list_2 = [k for k, _ in itertools.groupby(list_1)]
print(list_2)
[1, 2, 3]

2

Если править именно ваш код, то надо заменить цикл с for на while. Так можно лучше контролировать индексы. Верхняя граница цикла меняется когда удаляется элемент:

list_ = [1, 2, 2, 2, 3, 3]
j = 0
while j < len(list_) - 1:
    print(j)
    if list_[j] == list_[j + 1]:
        list_.pop(j)
    else:
        j += 1
print(list_)

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

3

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

Индекс i пробегает весь список без первого элемента. j отстаёт от него каждый раз когда соседние элементы равны. Различные элементы накапливаются в начале списка. Когда цикл окончен j указывает на хвост списка с "мусором". Этот хвост отрезается:

list_ = [1, 2, 2, 2, 3, 3]
j = 1
for i in range(1, len(list_)):
    if list_[i - 1] != list_[i]:
        list_[j] = list_[i]
        j += 1
del list_[j:]
print(list_)

4

Самый первый способ можно доработать так чтобы он не требовал дополнительной памяти:

import itertools


list_ = [1, 2, 2, 2, 3, 3]
list_[:] = (k for k, _ in itertools.groupby(list_))
print(list_)

5

Вариант без дополнительной памяти, библиотек и индексов:

def uniqs(seq):
    it = iter(seq)
    try:
        prev = next(it)
    except StopIteration:
        return
    yield prev
    for v in it:
        if v != prev:
            yield v
            prev = v


list_ = [1, 2, 2, 2, 3, 3]
list_[:] = uniqs(list_)
print(list_)

P.S. Последние три варианта реализуют один и тот же алгоритм различными средствами.

▲ 0

Проще это сделать вообще другим способом - с помощью спискового сокращения, чем мучиться с индексами и изменяющимся при итерировании списком:

lst=[1,2,2,2,3,3]
lst = [a for a,b in zip(lst, lst[1:] + [None]) if a != b]
print(lst)

Вывод:

[1, 2, 3]
▲ 0

Или одной строкой:

lst = [1, 2, 2, 2, 3, 3]    
lst = list(set(lst)) # [1, 2, 3]

P.S. Использовать зарезервированное Python-ом ключевое слово list не очень хорошая идея.