que tienen una lista de listas en Python:Python: la eliminación de duplicados de una lista de listas
k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]]
Y quieren eliminar elementos duplicados de la misma. Era si fuera una lista normal no de listas que podría usar set
. Pero desafortunadamente esa lista no es hashable y no puede hacer un conjunto de listas. Solo de tuplas. Así que puedo convertir todas las listas en tuplas y luego usar set y volver a las listas. Pero esto no es rápido.
¿Cómo se puede hacer de la manera más eficiente?
El resultado de la lista anterior debe ser:
k = [[5, 6, 2], [1, 2], [3], [4]]
No me importa acerca de preservar el orden.
Nota: this question es similar pero no es exactamente lo que necesito. Busqué SO pero no encontré el duplicado exacto.
Análisis comparativo:
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)
"loop in" (método cuadrática) más rápido de todos para las listas cortas. Para las listas largas, es más rápido que todos, excepto el método groupby. ¿Esto tiene sentido?
Para lista corta (el que en el código), 100.000 iteraciones:
[set] Elapsed: 1.3900001049
[sort] Elapsed: 0.891000032425
[groupby] Elapsed: 0.780999898911
[loop in] Elapsed: 0.578000068665
Para una lista más larga (el uno en el código duplicado 5 veces):
[set] Elapsed: 3.68700003624
[sort] Elapsed: 3.43799996376
[groupby] Elapsed: 1.03099989891
[loop in] Elapsed: 1.85900020599
Por "esto no es rápido", ¿quiere decir que usted lo ha programado y no es lo suficientemente rápido para su aplicación, o cree que no es rápido? –
@Torsten, parece demasiado copiar para ser un método inteligente. lo siento, presentimiento. copiar listas a tuplas, luego al conjunto, luego volver a la lista de listas (copiar nuevamente tuplas a listas) – zaharpopov
@zaharpopov: no es así como funciona Python, nada se * copiará *, solo nuevos contenedores para los elementos existentes (aunque para los ints , es más o menos lo mismo) –