2011-11-01 17 views
9

que tienen una estructura de datos como esto:¿Eliminar elementos duplicados de una lista de Python que contiene elementos que no se pueden pintar sin perder el orden?

[ 
[('A', '1'), ('B', '2')], 
[('A', '1'), ('B', '2')], 
[('A', '4'), ('C', '5')] 
] 

y quiero obtener esto:

[ 
[('A', '1'), ('B', '2')], 
[('A', '4'), ('C', '5')] 
] 

¿Hay una buena manera de hacer esto, preservando orden que se muestra?

Comandos para copiar y pegar:

sample = [] 
sample.append([('A', '1'), ('B', '2')]) 
sample.append([('A', '1'), ('B', '2')]) 
sample.append([('A', '4'), ('C', '5')]) 
+0

son los duplicados siempre adyacente? – Cameron

+0

@ Cameron: No necesariamente. – Legend

Respuesta

7

Ésta es una pregunta algo famoso que fue bien respondido por un famoso Pythonista hace mucho tiempo: http://code.activestate.com/recipes/52560-remove-duplicates-from-a-sequence/

Si se puede asumir registros iguales son adyacentes, hay una receta en el itertools docs:

from operator import itemgetter 
from itertools import groupby, imap 

def unique_justseen(iterable, key=None): 
    "List unique elements, preserving order. Remember only the element just seen." 
    # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B 
    # unique_justseen('ABBCcAD', str.lower) --> A B C A D 
    return imap(next, imap(itemgetter(1), groupby(iterable, key))) 

Si sólo puede asumir los elementos que pueden pedirse, aquí una variante utilizando la bisect m Odule Dadas n entradas con r valores únicos, su paso de búsqueda cuesta O (n log r). Si se encuentra un nuevo valor único, se inserta en la lista vista por un costo de O (r * r).

from bisect import bisect_left, insort 

def dedup(seq): 
    'Remove duplicates. Preserve order first seen. Assume orderable, but not hashable elements' 
    result = [] 
    seen = [] 
    for x in seq: 
     i = bisect_left(seen, x) 
     if i == len(seen) or seen[i] != x: 
      seen.insert(i, x) 
      result.append(x) 
    return result 
+0

La única receta para preservar el orden de Tim Peters es la fuerza bruta. Sin embargo, la receta de clasificación puede modificarse para mantener el rendimiento de O (n log n) mientras se preserva el orden. –

+0

Las variantes para preservar el orden son de Alex Martelli y se enumeran debajo del código de Tim en los comentarios. –

+2

Por lo que puedo decir, todas las variantes de Alex Martelli suponen que son viables. –

5

Aquí es una variante fin de preservación de la especie/idioma único. Esto le dará un rendimiento de O (n log n), siempre que sus artículos sean al menos ordenables.

def unique(a): 
    indices = sorted(range(len(a)), key=a.__getitem__) 
    indices = set(next(it) for k, it in 
        itertools.groupby(indices, key=a.__getitem__)) 
    return [x for i, x in enumerate(a) if i in indices] 

Ejemplo (con artículos hashable para simplificar):

>>> a = ['F', 'J', 'B', 'F', 'V', 'A', 'E', 'U', 'B', 'U', 'Z', 'K'] 
>>> unique(a) 
['F', 'J', 'B', 'V', 'A', 'E', 'U', 'Z', 'K'] 
+0

Agradable. Toma un minuto para ver cómo funciona. Inteligente. –

Cuestiones relacionadas