Самый быстрый способ удалить дубликаты в списке без импорта библиотек и использования наборов - PullRequest
1 голос
/ 18 апреля 2020

Я пытался удалить дубликаты из списка, используя следующий код:

a = [1,2,3,4,2,6,1,1,5,2]
res = []
[res.append(i) for i in a if i not in res]

Но я хотел бы сделать это без определения списка, который я хочу, как пустого списка (ie, пропустите строка res = []) вроде:

a = [1,2,3,4,2,6,1,1,5,2]
#Either:
res = [i for i in a if i not in res]
#Or:
[i for i in a if i not in 'this list'] # this list is not a string. I meant it as the list being comprehensed

Я хочу избежать импорта библиотеки и set()

Ответы [ 5 ]

6 голосов
/ 18 апреля 2020

Я думаю, что может работать на вас. Удаляет дубликаты из списка, сохраняя порядок.

newlist=[i for n,i in enumerate(L) if i not in L[:n]]
5 голосов
/ 18 апреля 2020

Для Python3 .6 + вы можете использовать dict.fromkeys():

>>> a = [1, 2, 3, 4, 2, 6, 1, 1, 5, 2]
>>> list(dict.fromkeys(a))
[1, 2, 3, 4, 6, 5]

Из документов :

Создать новый словарь с ключами от iterable и значениями, установленными в value.

Если вы используете более низкую версию Python, вам нужно будет использовать collections.OrderedDict для поддержания порядка:

>>> from collections import OrderedDict
>>> a = [1, 2, 3, 4, 2, 6, 1, 1, 5, 2]
>>> list(OrderedDict.fromkeys(a))
[1, 2, 3, 4, 6, 5]
4 голосов
/ 18 апреля 2020

вот простой тест с предлагаемыми решениями,

enter image description here

показывает, что dict.fromkeys будет работать лучше

from simple_benchmark import BenchmarkBuilder
import random


b = BenchmarkBuilder()

@b.add_function()
def AmitDavidson(a):
    return [i for n,i in enumerate(a) if i not in a[:n]]

@b.add_function()
def RoadRunner(a):
    return list(dict.fromkeys(a))

@b.add_function()
def DaniMesejo(a):
    return  list({k: '' for k in a})


@b.add_function()
def rdas(a):
    return  sorted(list(set(a)), key=lambda x: a.index(x))


@b.add_function()
def unwanted_set(a):
    return  list(set(a))


@b.add_arguments('List lenght')
def argument_provider():
    for exp in range(2, 18):
        size = 2**exp
        yield size, [random.randint(0, 10) for _ in range(size)]

r = b.run()
r.plot()
3 голосов
/ 18 апреля 2020

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

a = [1,2,3,4,2,6,1,1,5,2]
a_uniq = sorted(list(set(a)), key=lambda x: a.index(x))
print(a_uniq)
2 голосов
/ 18 апреля 2020

Однострочник, понимание, O(n), сохраняющий порядок в Python 3.6 +:

a = [1, 2, 3, 4, 2, 6, 1, 1, 5, 2]

res = list({k: '' for k in a})
print(res)
...