Nesta resposta, haverá duas seções: Duas soluções exclusivas e um gráfico de velocidade para soluções específicas.
Removendo itens duplicados
A maioria dessas respostas remove apenas itens duplicados que podem ser lavados , mas essa pergunta não implica que ele não precise apenas de itens laváveis , o que significa que vou oferecer algumas soluções que não exigem itens laváveis .
O contador é uma ferramenta poderosa na biblioteca padrão que pode ser perfeita para isso. Existe apenas uma outra solução que possui o Counter. No entanto, essa solução também é limitada a chaves laváveis .
Para permitir chaves laváveis no contador, criei uma classe Container, que tentará obter a função hash padrão do objeto, mas se falhar, tentará sua função de identidade. Ele também define um método eq e hash . Isso deve ser suficiente para permitir itens laváveis em nossa solução. Os objetos unhas laváveis serão tratados como se fossem laváveis. No entanto, essa função de hash usa identidade para objetos laváveis, o que significa que dois objetos iguais que são laváveis não funcionarão. Eu sugiro que você substitua isso e altere-o para usar o hash de um tipo mutável equivalente (como usar hash(tuple(my_list))
if my_list
é uma lista).
Eu também fiz duas soluções. Outra solução que mantém a ordem dos itens, usando uma subclasse de OrderedDict e Counter, chamada 'OrderedCounter'. Agora, aqui estão as funções:
from collections import OrderedDict, Counter
class Container:
def __init__(self, obj):
self.obj = obj
def __eq__(self, obj):
return self.obj == obj
def __hash__(self):
try:
return hash(self.obj)
except:
return id(self.obj)
class OrderedCounter(Counter, OrderedDict):
'Counter that remembers the order elements are first encountered'
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
def __reduce__(self):
return self.__class__, (OrderedDict(self),)
def remd(sequence):
cnt = Counter()
for x in sequence:
cnt[Container(x)] += 1
return [item.obj for item in cnt]
def oremd(sequence):
cnt = OrderedCounter()
for x in sequence:
cnt[Container(x)] += 1
return [item.obj for item in cnt]
remd é uma classificação não ordenada, oremd é uma classificação ordenada. Você pode dizer claramente qual é o mais rápido, mas eu explicarei de qualquer maneira. A classificação não ordenada é um pouco mais rápida. Ele mantém menos dados, pois não precisa de ordem.
Agora, eu também queria mostrar as comparações de velocidade de cada resposta. Então, eu vou fazer isso agora.
Qual função é a mais rápida?
Para remover duplicatas, reuni 10 funções com algumas respostas. Calculei a velocidade de cada função e a coloquei em um gráfico usando matplotlib.pyplot .
Dividi isso em três rodadas de gráficos. Um hashable é qualquer objeto que possa ser hash, um unhashable é qualquer objeto que não possa ser hash. Uma sequência ordenada é uma sequência que preserva a ordem, uma sequência não ordenada não preserva a ordem. Agora, aqui estão mais alguns termos:
O Hashable desordenado era para qualquer método que removeu duplicatas, que não precisavam necessariamente manter o pedido. Não precisava trabalhar para unhashables, mas podia.
O Hashable ordenado era para qualquer método que mantivesse a ordem dos itens na lista, mas não precisava funcionar para unhashables, mas podia.
O pedido de Unhashable era qualquer método que mantivesse a ordem dos itens da lista e funcionasse para unhashables.
No eixo y é a quantidade de segundos que levou.
No eixo x é o número ao qual a função foi aplicada.
Geramos seqüências para hashables não ordenados e ordenamos hashables com a seguinte compreensão: [list(range(x)) + list(range(x)) for x in range(0, 1000, 10)]
Para unhashables encomendadas: [[list(range(y)) + list(range(y)) for y in range(x)] for x in range(0, 1000, 10)]
Observe que há um 'passo' no intervalo, porque sem ele, isso levaria 10 vezes mais. Também porque, na minha opinião pessoal, achei que poderia parecer um pouco mais fácil de ler.
Observe também que as teclas na legenda são o que tentei adivinhar como as partes mais vitais da função. Quanto a qual função faz o pior ou o melhor? O gráfico fala por si.
Com isso resolvido, aqui estão os gráficos.
Hashables não ordenados
(Mais zoom)
Hashables ordenados
(Mais zoom)
Encomendado Unhashables
(Mais zoom)