Suppresion de doublons dans une liste [Python] - Python - Programmation
Marsh Posté le 29-04-2007 à 09:27:16
Salut, tu peux utiliser set, cf http://docs.python.org/lib/module-sets.html.
Code :
|
avec les dictionnaires, ca donne:
Code :
|
Marsh Posté le 29-04-2007 à 14:01:56
elpacificator a écrit : Salut, tu peux utiliser set, cf http://docs.python.org/lib/module-sets.html.
avec les dictionnaires, ca donne:
|
Ouais mais en faisant ça tu perds l'ordre de ta liste
Code :
|
Par contre ça ne fonctionne que si les objets contenus dans la liste sont hashables
Marsh Posté le 29-04-2007 à 20:01:17
Code :
|
Marsh Posté le 29-04-2007 à 20:15:31
elpacificator a écrit :
|
On peut aussi faire comme ça, mais le lookup dans une liste (le "not in", donc) se fait en O(n) alors que dans un set c'est en O(1), donc sur une grosse liste le ralentissement va être sensible, surtout si il y a un grand nombre de redondances (donc un faible nombre d'insertions par rapport au nombre de lookups, puisque je suis obligé de faire un `append` et un `add` pour chaque insertion alors que tu ne fais qu'un `append`)
Je me suis complètement planté dans mon analyse du "worst-case", apparement l'insertion dans un set a un coût extrèmement faible, donc en réalité le "worst case" de la méthode d'elpacificator c'est quand on a très peu de redondances, donc que la liste dans laquelle on fait les insertions augmente très vite, donc qu'il y a un très très grand nombre de valeurs dans le lookup. Parce que avec un maximum de redondances, la liste ne dépasse pas 1 élément, donc le lookup se fait en temps constant en permanence, donc ma méthode "perd" du fait de l'initialisation de 2 conteneurs + 2 inserts de l'unique valeur à insérer
Marsh Posté le 29-04-2007 à 20:23:08
Masklinn, toujours à la pointe de l'optimisation
En fonction de la taille de la liste, je preferais ta solution.
Bien joué.
Marsh Posté le 29-04-2007 à 20:45:53
elpacificator a écrit : Masklinn, toujours à la pointe de l'optimisation |
J'ai fait un test, parce qu'en fait j'avais peur de passer pour un con (l'overhead du maintient de deux conteneurs et des insertions doublées pouvait être beaucoup plus coûteux que prévu quand on a beaucoup de redondances)...
Au final ça donne ça (nub1 est ta méthode placée dans une fonction, nub2 est ma méthode, le code est après si tu veux tester sur ta machine)
no redundancy (range(10000)) 100 rendundancies (randint on 100 values for a list of 10000) 1000 rendundancies (randint on 10 values for a list of 10000) only redundancies (list of 10000 '1's) |
À part avec un maximum de redondance, nub1 a des performances inférieures à nub2, et en fait en dessous de 10% de redondances il a des perfs complètement catastrophiques
Voilà le code de test, si j'ai fait une connerie (pas la peine de me dire que j'aurais pu factoriser les 4 tests en une seule fonction, c'était pas l'intérêt du truc )
Code :
|
edit: testé sur un A64 4400+, donc cadencé à 2.2GHz, changez le paramètre ITERATIONS si votre CPU est moins véloce parce que 3mn20s ça fait déjà beaucoup
Marsh Posté le 29-04-2007 à 21:33:51
Code :
|
sur un P4 3.06GHz HT.
Marsh Posté le 29-04-2007 à 22:07:03
Whoa, nub2 tourne vachement moins bien sur un P4 (alors que nub1 tourne sensiblement de la même manière, on voit juste une différence ce fréquence)
J'me demande à quoi c'est dû
Le cache ptet
En tout cas, on voit bien qu'aux constantes près le comportement est le même, nub2 est beaucoup plus régulier dans toutes les situations et n'a pas d'explosion du temps de calcul
Marsh Posté le 29-04-2007 à 06:17:34
Bonjour,
Je me souviens d'une astuce assez compliquée (conversion de la liste en dictionnaire, puis retour en liste) pour supprimer les doublons d'une liste, y'aurait-il plus simple?
Message édité par chaica le 29-04-2007 à 06:17:55