Обновление: сравнение разных подходов
Существуют три способа достижения цели удаления соседних повторяющихся элементов в отсортированном списке, то есть удаления всех дубликатов:
- с использованием
groupby
(только смежные элементы, требуется начальная сортировка)
- с использованием
OrderedDict
(все дубликаты удалены)
- с использованием
sorted(list(set(_)))
(все дубликаты удалены, порядок восстановлен путем сортировки).
Я сравнил время выполнения различных решений, используя:
from timeit import timeit
print('groupby:', timeit('from itertools import groupby; l = [x // 5 for x in range(1000)]; [k for k, _ in groupby(l)]'))
print('OrderedDict:', timeit('from collections import OrderedDict; l = [x // 5 for x in range(1000)]; list(OrderedDict.fromkeys(l))'))
print('Set:', timeit('l = [x // 5 for x in range(1000)]; sorted(list(set(l)))'))
> groupby: 78.83623623599942
> OrderedDict: 94.54144410200024
> Set: 65.60372123999969
Обратите внимание, что подход set
является самым быстрым среди всех альтернатив.
Старый ответ
Python сначала оценивает понимание списка, а затем присваивает его newList
, поэтому вы не можете обратиться к нему во время выполнения понимания списка. Для иллюстрации рассмотрим следующий код:
randList = [1, 2, 2, 3, 4, 4, 5]
newList = []
newList = [num for num in randList if print(newList)]
> []
> []
> []
> …
Это становится еще более очевидным, если вы попытаетесь:
# Do not initialize newList2
newList2 = [num for num in randList if print(newList2)]
> NameError: name 'newList2' is not defined
Вы можете удалить дубликаты, превратив randList в набор:
sorted(list(set(randlist)))
> [1, 2, 3, 4, 5]
Имейте в виду, что это удаляет все дубликаты (не только смежные), и порядок не сохраняется. Первое также верно для предложенного вами решения с циклом.
edit : добавлено предложение sorted
относительно спецификации требуемого заказа.