Par exemple, étant donné la liste ['one', 'two', 'one']
, l'algorithme devrait retourner True
, alors que donné, ['one', 'two', 'three']
il devrait retourner False
.
python
string
list
duplicates
teggy
la source
la source
Recommandé pour les listes courtes uniquement:
Ne pas utiliser sur une longue liste - cela peut prendre un temps proportionnel au carré du nombre d'éléments dans la liste!
Pour des listes plus longues avec des éléments hachables (chaînes, nombres, etc.):
Si vos éléments ne sont pas hachables (sous-listes, dictionnaires, etc.), ils deviennent plus poilus, bien qu'il soit toujours possible d'obtenir O (N logN) s'ils sont au moins comparables. Mais vous devez connaître ou tester les caractéristiques des éléments (hachables ou non, comparables ou non) pour obtenir les meilleures performances possibles - O (N) pour les hachables, O (N log N) pour les comparables non hachables, sinon c'est à O (N au carré) et on ne peut rien y faire :-(.
la source
all
tous les comptes soient 1). Un dict avec toutes les valeurs True, que vous mentionnez également, est un mimique ridiculement et inutilement gonflé de aset
, sans aucune valeur ajoutée. Big-O n'est pas tout dans la programmation.C'est vieux, mais les réponses ici m'ont conduit à une solution légèrement différente. Si vous êtes prêt à abuser de vos compréhensions, vous pouvez vous mettre en court-circuit de cette façon.
la source
Si vous aimez le style de programmation fonctionnelle, voici une fonction utile, un code auto-documenté et testé à l'aide de doctest .
De là, vous pouvez tester l'unicité en vérifiant si le deuxième élément de la paire retournée est vide:
Notez que ce n'est pas efficace car vous construisez explicitement la décomposition. Mais dans le cadre de l'utilisation de la réduction, vous pouvez arriver à quelque chose d'équivalent (mais légèrement moins efficace) pour répondre 5:
la source
J'ai pensé qu'il serait utile de comparer les timings des différentes solutions présentées ici. Pour cela, j'ai utilisé ma propre bibliothèque
simple_benchmark
:Donc en effet pour ce cas la solution de Denis Otkidach est la plus rapide.
Certaines des approches présentent également une courbe beaucoup plus raide, ce sont les approches qui échelonnent quadratique avec le nombre d'éléments (première solution d'Alex Martellis, wjandrea et les deux solutions de Xavier Decorets). Il est également important de mentionner que la solution pandas de Keiku a un très grand facteur constant. Mais pour les listes plus grandes, il rattrape presque les autres solutions.
Et au cas où le duplicata serait à la première position. Ceci est utile pour voir quelles solutions sont en court-circuit:
Ici, plusieurs approches ne court-circuitent pas: Kaiku, Frank, Xavier_Decoret (première solution), Turn, Alex Martelli (première solution) et l'approche présentée par Denis Otkidach (qui a été la plus rapide dans le cas sans doublon).
J'ai inclus une fonction de ma propre bibliothèque ici:
iteration_utilities.all_distinct
qui peut rivaliser avec la solution la plus rapide dans le cas sans doublons et qui fonctionne en temps constant pour le cas de duplication au début (mais pas aussi rapide).Le code du benchmark:
Et pour les arguments:
la source
J'ai récemment répondu à une question connexe pour établir tous les doublons dans une liste, à l'aide d'un générateur. Il a l'avantage que s'il est utilisé simplement pour établir «s'il y a un doublon», il vous suffit d'obtenir le premier élément et le reste peut être ignoré, ce qui est le raccourci ultime.
C'est une approche intéressante basée sur des ensembles que j'ai adaptée directement de moooeeeep :
En conséquence, une liste complète des dupes serait
list(getDupes(etc))
. Pour tester simplement "s'il y a" une dupe, il doit être encapsulé comme suit:Cela s'adapte bien et fournit des temps de fonctionnement cohérents où que le dupe se trouve dans la liste - j'ai testé avec des listes allant jusqu'à 1 m d'entrées. Si vous savez quelque chose sur les données, en particulier, que des dupes sont susceptibles d'apparaître dans la première moitié, ou d'autres choses qui vous permettent de biaiser vos exigences, comme avoir besoin d'obtenir les dupes réelles, alors il existe quelques localisateurs de dupes vraiment alternatifs. cela pourrait surpasser. Les deux que je recommande sont ...
Approche simple basée sur les dict, très lisible:
Tirez parti d'itertools (essentiellement un ifilter / izip / tee) sur la liste triée, très efficace si vous obtenez toutes les dupes, mais pas aussi rapidement pour obtenir le premier:
Ce sont les meilleurs parmi les approches que j'ai essayées pour la liste complète des dupes , la première dupe se produisant n'importe où dans une liste d'éléments de 1 m du début au milieu. Il était surprenant de constater à quel point l'étape de tri était peu chargée. Votre kilométrage peut varier, mais voici mes résultats chronométrés spécifiques:
la source
.next()
appel dans votre deuxième bloc de code ne fonctionne pas sur Python 3.x. Je pense que celanext(getDupes(l))
devrait fonctionner avec les versions de Python, il peut donc être judicieux de changer cela.ifilter
etìzip
peut être simplement remplacé par le intégréfilter
etzip
dans Python 3.x.Une autre façon de procéder de manière succincte est d' utiliser Counter .
Pour simplement déterminer s'il y a des doublons dans la liste d'origine:
Ou pour obtenir une liste des éléments qui ont des doublons:
la source
la source
J'ai trouvé que cela offrait les meilleures performances car il court-circuitait l'opération lors de la première duplication trouvée, alors cet algorithme a une complexité temporelle et spatiale O (n) où n est la longueur de la liste:
la source
Je ne sais pas vraiment ce que fait le décor dans les coulisses, alors j'aime juste rester simple.
la source
Une solution plus simple est la suivante. Vérifiez simplement Vrai / Faux avec la
.duplicated()
méthode pandas , puis prenez la somme. Veuillez également consulter pandas.Series.duplicated - documentation pandas 0.24.1la source
Si la liste contient des éléments non détachables, vous pouvez utiliser la solution d'Alex Martelli mais avec une liste au lieu d'un ensemble, bien qu'elle soit plus lente pour les entrées plus importantes: O (N ^ 2).
la source
J'ai utilisé l'approche de pyrospade, pour sa simplicité, et l'ai légèrement modifiée sur une courte liste faite à partir du registre Windows insensible à la casse.
Si la chaîne de valeur PATH brute est divisée en chemins individuels, tous les chemins `` nuls '' (chaînes vides ou d'espaces uniquement) peuvent être supprimés en utilisant:
Le PATH d'origine a à la fois des entrées «nulles» et des doublons à des fins de test:
Les chemins nuls ont été supprimés, mais il y a toujours des doublons, par exemple (1, 3) et (13, 20):
Et enfin, les dupes ont été supprimés:
la source
la source