Qual é a melhor maneira (melhor como da maneira convencional) de verificar se todos os elementos de uma lista são únicos?
Minha abordagem atual usando um Counter
é:
>>> x = [1, 1, 1, 2, 3, 4, 5, 6, 2]
>>> counter = Counter(x)
>>> for values in counter.itervalues():
if values > 1:
# do something
Posso fazer melhor?
len(x) > len(set(x))
é True quando os elementos emx
NÃO são exclusivos. O título desta pergunta pergunta exatamente o oposto: "Verificando se todos os elementos em uma lista são únicos"Aqui está uma linha dupla que também fará a saída antecipada:
Se os elementos de x não tiverem hash, você terá que recorrer ao uso de uma lista para
seen
:fonte
Uma solução de saída antecipada pode ser
no entanto, para casos pequenos ou se a saída antecipada não for o caso comum, eu esperaria
len(x) != len(set(x))
ser o método mais rápido.fonte
s = set()
...return not any(s.add(x) if x not in s else True for x in g)
len(x) != len(set(x))
ser mais rápido do que isso se a saída antecipada não é comum? Ambas as operações não são O (len (x)) ? (ondex
está a lista original)if x in s
dentro do O (len (x)) o loop.para velocidade:
fonte
Que tal adicionar todas as entradas a um conjunto e verificar seu comprimento?
fonte
len()
.Alternativa a a
set
, você pode usar adict
.fonte
Outra abordagem totalmente, usando classificado e agrupado:
Ele exige uma classificação, mas sai no primeiro valor repetido.
fonte
groupby
e achei essa resposta. Acho isso muito elegante, pois é uma expressão única e funciona com as ferramentas integradas sem exigir qualquer variável extra ou instrução de loop.id()
função para classificá-los, pois este é um pré-requisito paragroupby()
funcionar:groupby(sorted(seq), key=id)
Aqui está uma versão recursiva O (N 2 ) para diversão:
fonte
Aqui está uma função de saída precoce recursiva:
É rápido o suficiente para mim, sem usar conversões estranhas (lentas) e, ao mesmo tempo, ter uma abordagem de estilo funcional.
fonte
H in T
faz uma pesquisa linear eT = L[1:]
copia a parte fatiada da lista, então isso será muito mais lento do que as outras soluções que foram sugeridas em listas grandes. É O (N ^ 2), eu acho, enquanto a maioria dos outros são O (N) (conjuntos) ou O (N log N) (soluções baseadas em classificação).Que tal agora
fonte
Você pode usar a sintaxe de Yan (len (x)> len (set (x))), mas em vez de set (x), defina uma função:
e faça len (x)> len (f5 (x)). Isso será rápido e também preservará a ordem.
O código foi retirado de: http://www.peterbe.com/plog/uniqifiers-benchmark
fonte
x = range(1000000) + range(1000000)
, executar set (x) é mais rápido do que f5 (x). A ordem não é um requisito na questão, mas mesmo executando ordenado (conjunto (x)) ainda é mais rápido do que f5 (x)Usando uma abordagem semelhante em um dataframe Pandas para testar se o conteúdo de uma coluna contém valores únicos:
Para mim, isso é instantâneo em uma variável int em um quadro de datas contendo mais de um milhão de linhas.
fonte
todas as respostas acima são boas, mas eu prefiro usar o
all_unique
exemplo de 30 segundos de pythonvocê precisa usar
set()
na lista fornecida para remover duplicatas, compare seu comprimento com o comprimento da lista.ele retorna
True
se todos os valores em uma lista plana sãounique
,False
caso contráriofonte
Para iniciantes:
fonte