Por exemplo, dada a lista ['one', 'two', 'one']
, o algoritmo deve retornar True
, enquanto que, dado ['one', 'two', 'three']
que deve retornar False
.
python
string
list
duplicates
teggy
fonte
fonte
Recomendado apenas para listas curtas :
Você não usar em uma longa lista - pode levar tempo proporcional ao quadrado do número de itens na lista!
Para listas mais longas com itens que podem ser lavados (cadeias, números etc.):
Se seus itens não forem laváveis (sublistas, dictos, etc.), eles ficarão mais peludos, embora ainda seja possível obter O (N logN) se forem pelo menos comparáveis. Mas você precisa conhecer ou testar as características dos itens (lavável ou não, comparável ou não) para obter o melhor desempenho possível - O (N) para hashables, O (N log N) para comparáveis não laváveis, caso contrário é O (N ao quadrado) e não há nada que se possa fazer sobre isso :-(.
fonte
all
número de contagens é 1). Um ditado com todos os valores True, que você também menciona, é um mimetismo ridículo e inutilmente inchado de aset
, sem nenhum valor agregado. Big-O não é tudo em programação.Isso é antigo, mas as respostas aqui me levaram a uma solução ligeiramente diferente. Se você está disposto a abusar das compreensões, pode entrar em curto-circuito dessa maneira.
fonte
Se você gosta do estilo de programação funcional, aqui está uma função útil, código auto-documentado e testado usando doctest .
A partir daí, você pode testar a unicidade verificando se o segundo elemento do par retornado está vazio:
Observe que isso não é eficiente, pois você está construindo explicitamente a decomposição. Mas, na linha do uso de reduzir, você pode chegar a algo equivalente (mas um pouco menos eficiente) para responder 5:
fonte
Eu pensei que seria útil comparar os horários das diferentes soluções apresentadas aqui. Para isso, usei minha própria biblioteca
simple_benchmark
:Portanto, neste caso, a solução de Denis Otkidach é a mais rápida.
Algumas das abordagens também exibem uma curva muito mais íngreme; essas são abordagens quadráticas com o número de elementos (primeira solução de Alex Martellis, wjandrea e ambas as soluções de Xavier Decorets). Também é importante mencionar que a solução de pandas do Keiku tem um fator constante muito grande. Mas para listas maiores, quase alcança as outras soluções.
E caso a duplicata esteja na primeira posição. Isso é útil para ver quais soluções estão em curto-circuito:
Aqui, várias abordagens não causam um curto-circuito: Kaiku, Frank, Xavier_Decoret (primeira solução), Turn, Alex Martelli (primeira solução) e a abordagem apresentada por Denis Otkidach (que foi o mais rápido no caso sem duplicação).
Eu incluí uma função da minha própria biblioteca aqui:
iteration_utilities.all_distinct
que pode competir com a solução mais rápida no caso sem duplicatas e executa em tempo constante no caso de duplicação no início (embora não seja tão rápido).O código para o benchmark:
E para os argumentos:
fonte
Recentemente, respondi a uma pergunta relacionada para estabelecer todas as duplicatas em uma lista, usando um gerador. Tem a vantagem de que, se usado apenas para estabelecer 'se houver uma duplicata', você precisará obter o primeiro item e o restante poderá ser ignorado, que é o atalho definitivo.
Esta é uma abordagem interessante baseada em conjuntos que adaptei diretamente do moooeeeep :
Assim, uma lista completa de bobagens seria
list(getDupes(etc))
. Para simplesmente testar "se" há um dupe, ele deve ser empacotado da seguinte maneira:Isso se adapta bem e fornece tempos de operação consistentes onde quer que o dupe esteja na lista - testei com listas de entradas de até 1 milhão. Se você sabe algo sobre os dados, especificamente, que os dupes provavelmente aparecerão no primeiro semestre, ou outras coisas que permitem distorcer seus requisitos, como a necessidade de obter os dupes reais, existem alguns localizadores de dupe realmente alternativos que pode ter um desempenho superior. Os dois que eu recomendo são ...
Abordagem simples baseada em dict, muito legível:
Aproveite as ferramentas (essencialmente um ifilter / izip / tee) na lista classificada, muito eficiente se você estiver obtendo todos os truques, embora não seja tão rápido para obter apenas o primeiro:
Esses foram os melhores desempenhos das abordagens que tentei para a lista completa de enganados , com o primeiro ocorrendo em qualquer lugar de uma lista de elementos de 1 metro do começo ao meio. Foi surpreendente o quão pouco sobrecarga a etapa de classificação acrescentou. Sua milhagem pode variar, mas aqui estão meus resultados cronometrados específicos:
fonte
.next()
chamada no seu segundo bloco de código não funciona no Python 3.x. Eu acho quenext(getDupes(l))
deve funcionar em versões do Python, por isso pode fazer sentido mudar isso.ifilter
eìzip
pode ser simplesmente substituído pelo internofilter
ezip
no Python 3.x.Outra maneira de fazer isso de forma sucinta é com o Counter .
Para determinar apenas se há duplicatas na lista original:
Ou, para obter uma lista de itens com duplicatas:
fonte
fonte
Descobri que esse desempenho era o melhor desempenho porque ele provoca um curto-circuito na operação quando foi duplicada, e esse algoritmo possui complexidade de tempo e espaço O (n) em que n é o comprimento da lista:
fonte
Eu realmente não sei o que o set faz nos bastidores, então eu só gosto de manter as coisas simples.
fonte
Uma solução mais simples é a seguinte. Apenas marque True / False com o
.duplicated()
método pandas e depois faça a soma. Consulte também pandas.Series.duplicated - documentação do pandas 0.24.1fonte
Se a lista contiver itens laváveis, você pode usar a solução de Alex Martelli, mas com uma lista em vez de um conjunto, embora seja mais lento para entradas maiores: O (N ^ 2).
fonte
Eu usei a abordagem do pyrospade, por sua simplicidade, e modifiquei isso levemente em uma pequena lista feita a partir do registro do Windows que não diferencia maiúsculas de minúsculas.
Se a cadeia de valor PATH não processada for dividida em caminhos individuais, todos os caminhos 'nulos' (cadeias vazias ou somente espaços em branco) poderão ser removidos usando:
O PATH original possui entradas 'nulas' e duplicatas para fins de teste:
Os caminhos nulos foram removidos, mas ainda possuem duplicatas, por exemplo, (1, 3) e (13, 20):
E, finalmente, os burros foram removidos:
fonte
fonte