Obteniendo tuplas únicas de un conjunto de python

Actualmente tengo un set como el siguiente:

{(a,b), (b,a), (c,b), (b,c)} 

Lo que me gustaría tener es:

 {(a,b), (c,b)} 

Como puede observar, los valores duplicados se han eliminado completamente para que dos tuplas nunca tengan los mismos elementos en el interior, independientemente del orden.

¿Cómo puedo decirle al conjunto que ignore el orden de los elementos en la tupla y simplemente verifique los valores entre las tuplas?

Bien, entonces tienes un conjunto {c1, c2, c3, ...} , donde cada cN es una colección de algún tipo.

Si no te importa el orden de los elementos en cN , pero te importa que sea único (sin tener en cuenta el orden), cN debería ser un frozenset 1 en lugar de una tuple :

 >>> orig = {("a", "b"), ("b", "a"), ("c", "b"), ("b", "c")} >>> uniq = {frozenset(c) for c in orig} >>> uniq {frozenset(['b', 'a']), frozenset(['b', 'c'])} 

Como regla general, elegir un tipo de datos apropiado de los proporcionados por Python será más sencillo que definir y mantener clases personalizadas.


1 No puede ser un set , porque como miembro de un set más grande debe ser hashable.

Solución bastante fea y directa. Implementas la igualdad para tratar (2, 3) y (3, 2) como objetos iguales, implementas __hash__ para no permitir miembros iguales en el conjunto. Puede acceder a los miembros como en las aseveraciones a continuación.

No estoy contento con el aspecto de la función de hash, pero de todos modos, es solo una prueba de concepto. Esperemos que encuentres una solución más elegante para calcularla sin colisiones.

 class WhateverItIs(object): def __init__(self, a, b): self.a = a self.b = b def __eq__(self, other): return ((self.a == other.a and self.b == other.b) or (self.a == other.b and self.b == other.a)) def __hash__(self): return hash(tuple(sorted((self.a, self.b)))) o1 = WhateverItIs(2, 3) o2 = WhateverItIs(3, 2) o3 = WhateverItIs(4, 3) assert {o1, o2, o3} in [{o1, o3}, {o2, o3}] assert o1 == o2 assert o1.a == 2 assert o1.b == 3 assert o2.a == 3 assert o2.b == 2 assert o3.a == 4 assert o3.b == 3 
 >>> aa = [('a', 'b'), ('c', 'd'), ('b', 'a')] >>> seen = set() >>> a = [seen.add((x,y)) for x,y in aa if (x,y) and (y,x) not in seen ] >>> list(seen) [('a', 'b'), ('c', 'd')]