Toma tuplas únicas en la lista de python, independientemente del orden

Tengo una lista de python:

[ (2,2),(2,3),(1,4),(2,2), etc...] 

Lo que necesito es algún tipo de función que lo reduzca a sus componentes únicos … que serían, en la lista anterior:

 [ (2,2),(2,3),(1,4) ] 

El único numpy no hace exactamente esto. Se me ocurre una manera de hacerlo: convertir mis tuplas en números, [22,23,14,etc.] , Encontrar a los únicos y volver a trabajar desde allí … pero no sé si la complejidad ganó. No te salgas de las manos. ¿Hay alguna función que haga lo que estoy tratando de hacer con las tuplas?


Aquí hay una muestra de código que demuestra el problema:

  import numpy as np x = [(2,2),(2,2),(2,3)] y = np.unique(x) 

devuelve: y: [2 3]

Y aquí está la implementación de la solución que demuestra la solución:

  x = [(2,2),(2,2),(2,3)] y = list(set(x)) 

devuelve y: [(2,2), (2,3)]

simplemente podrías hacer

 y = np.unique(x, axis=0) z = [] for i in y: z.append(tuple(i)) 

La razón es que una lista de tuplas se interpreta por numpy como una matriz 2D. Al establecer axis = 0, le pediría a Numpy que no aplane la matriz y devuelva filas únicas.

Si el orden no importa

Si el orden del resultado no es crítico, puede convertir su lista en un conjunto (porque las tuplas son hashables) y volver a convertir el conjunto en una lista:

 >>> l = [(2,2),(2,3),(1,4),(2,2)] >>> list(set(l)) [(2, 3), (1, 4), (2, 2)] 

Si el orden importa

(ACTUALIZAR)

A partir de CPython 3.6 (o cualquier versión de Python 3.7), los diccionarios regulares recuerdan su orden de inserción, por lo que puede simplemente emitir.

 >>> l = [(2,2),(2,3),(1,4),(2,2)] >>> list(dict.fromkeys(l)) [(2, 2), (2, 3), (1, 4)] 

(ANTIGUA RESPUESTA)

Si el orden es importante, la forma canónica de filtrar los duplicados es la siguiente:

 >>> seen = set() >>> result = [] >>> for item in l: ... if item not in seen: ... seen.add(item) ... result.append(item) ... >>> result [(2, 2), (2, 3), (1, 4)] 

Finalmente, un poco más lento y un poco más intrépido, puedes abusar de un OrderedDict como un conjunto ordenado:

 >>> from collections import OrderedDict >>> OrderedDict.fromkeys(l).keys() # or list(OrderedDict.fromkeys(l)) if using a version where keys() does not return a list [(2, 2), (2, 3), (1, 4)] 

El uso de un set eliminará los duplicados, y luego creará una list partir de él:

 >>> list(set([ (2,2),(2,3),(1,4),(2,2) ])) [(2, 3), (1, 4), (2, 2)] 

set() eliminará todos los duplicados, y luego podrá volver a ponerlo en una lista:

 unique = list(set(mylist)) 

El uso de set() , sin embargo, matará su pedido. Si el orden es importante, puede utilizar una lista de comprensión que compruebe si el valor ya existe anteriormente en la lista:

 unique = [v for i,v in enumerate(mylist) if v not in mylist[:i]] 

Sin embargo, esa solución es un poco lenta, así que puedes hacerlo así:

 unique = [] for tup in mylist: if tup not in unique: unique.append(tup)