j'ai une liste de listes en Python:Python: la suppression des doublons dans une liste de listes
k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]]
Et je veux supprimer les doublons de lui. Était-ce si c'était une liste normale de listes que je pouvais utiliser set
. Mais malheureux cette liste n'est pas hashable et ne peut pas faire un ensemble de listes. Seulement des tuples. Je peux donc transformer toutes les listes en tuples puis utiliser set et retourner aux listes. Mais ce n'est pas rapide.
Comment cela peut-il être fait de la manière la plus efficace?
Le résultat de la liste ci-dessus doit être:
k = [[5, 6, 2], [1, 2], [3], [4]]
Je ne me soucie pas de préserver l'ordre.
Note: this question est similaire mais pas tout à fait ce dont j'ai besoin. Cherché SO mais n'a pas trouvé le double exact.
Analyse comparative:
import itertools, time
class Timer(object):
def __init__(self, name=None):
self.name = name
def __enter__(self):
self.tstart = time.time()
def __exit__(self, type, value, traceback):
if self.name:
print '[%s]' % self.name,
print 'Elapsed: %s' % (time.time() - self.tstart)
k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [5, 2], [6], [8], [9]] * 5
N = 100000
print len(k)
with Timer('set'):
for i in xrange(N):
kt = [tuple(i) for i in k]
skt = set(kt)
kk = [list(i) for i in skt]
with Timer('sort'):
for i in xrange(N):
ks = sorted(k)
dedup = [ks[i] for i in xrange(len(ks)) if i == 0 or ks[i] != ks[i-1]]
with Timer('groupby'):
for i in xrange(N):
k = sorted(k)
dedup = list(k for k, _ in itertools.groupby(k))
with Timer('loop in'):
for i in xrange(N):
new_k = []
for elem in k:
if elem not in new_k:
new_k.append(elem)
"boucle" (méthode quadratique) le plus rapide de toutes les listes courtes. Pour les longues listes, c'est plus rapide que tout le monde sauf la méthode groupby. Est-ce que ça a du sens?
Pour la liste courte (celle dans le code), 100000 itérations:
[set] Elapsed: 1.3900001049
[sort] Elapsed: 0.891000032425
[groupby] Elapsed: 0.780999898911
[loop in] Elapsed: 0.578000068665
Pour une liste plus longue (une dans le code dupliqués 5 fois):
[set] Elapsed: 3.68700003624
[sort] Elapsed: 3.43799996376
[groupby] Elapsed: 1.03099989891
[loop in] Elapsed: 1.85900020599
Par « ce n'est pas rapide », voulez-vous dire que vous l'avez chronométré et ce n'est pas assez rapide pour votre application, ou que vous pensez que ce n'est pas rapide? –
@Torsten, il semble juste trop de copier pour être une méthode intelligente. désolé, le sentiment de l'intestin. copier les listes en tuples, puis en set, puis revenir à la liste des listes (copier à nouveau les tuples dans les listes) – zaharpopov
@zaharpopov: ce n'est pas comme cela que Python fonctionne, rien ne sera * copié *, juste de nouveaux conteneurs pour les éléments existants , c'est à peu près pareil) –