2012-10-01 15 views
7

¿Hay alguna forma de hacer una lista de comprensión en Python que solo contenga elementos únicos?Comprensión de la lista de Python, con elementos únicos

Mi idea original era utilizar algo como esto: new_items = [unicode(item) for item in items]

Sin embargo, más tarde me di cuenta que necesitaba para omitir los elementos duplicados. Así que terminé con esta monstruosidad fea:

unique_items = [] 
for item in items : 
    unicode_item = unicode(item) 
    if unicode_item not in unique_items : 
     unique_items.append(unicode_item) 

Ahora bien, esto es mucho menos bonita (y legible) que una simple lista por comprensión. Entonces, ¿hay alguna manera de hacer una lista de comprensión equivalente al código anterior?

También importa el orden, por lo que no puedo simplemente usar un conjunto de comprensión.

+0

interesante, mi primer pensamiento fue que se puede hacer en el filtrado de listas por comprensión, pero luego me di cuenta de que había necesita acceso a la nueva lista que está creando en la condición de filtro. – Davy8

+0

Si el orden es importante, ¿cómo sé qué instancia de un artículo repetido usar? ¿El primero, el último o uno en el medio? – lvella

+1

posible duplicado de [¿Cómo se eliminan los duplicados de una lista en Python conservando el orden?] (Http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in -python-while-preservando-orden) – mgilson

Respuesta

17

Bueno, no hay un conjunto ordenado, pero podemos hacer mal uso OrderedDict:

from collections import OrderedDict 
t = "never gonna give you up" 
OrderedDict.fromkeys(t).keys() 

Da:

['n', 'e', 'v', 'r', ' ', 'g', 'o', 'a', 'i', 'y', 'u', 'p'] 
+0

Oh, muy agradable. En una nota lateral, intente usar 'repeat (None)' de 'itertools' en lugar de' [None] * len (t) ' – Dunes

+3

¿Qué tal' OrderedDict.fromkeys (t) .keys() 'en su lugar? [Tenga en cuenta que este enfoque, así como el enfoque establecido, nos limita a los elementos con capacidad de manipulación.] – DSM

+0

Sí, mejor. Gracias por su sugerencia! – Michael

4

Haz que sea una función auxiliar, como tal.

def unique_iter(iterable): 
    seen = set() 
    for item in iterable: 
    if item in seen: 
     continue 
    seen.add(item) 
    yield item 

for ch in unique_iter("never gonna give you up"): 
    print ch, 

salidas

nevrgoaiyup

6

que corta un trazador de líneas podría ser:

s = "some string" 
unique_items = [unicode(ch) for ch in sorted(set(s), key=s.index)] 
+1

Funciona, pero no es muy eficiente para listas más grandes. – l4mpi

+1

No, pero es corto y fácil de entender su intención. – Dunes

7

Su idea original trabaja con un conjunto de comprensión:

new_items = {unicode(item) for item in items} 
Cuestiones relacionadas