Tengo una gran cantidad de objetos que necesito almacenar en la memoria para procesarlos en Python. Específicamente, estoy tratando de eliminar duplicados de un gran conjunto de objetos. Quiero considerar dos objetos "iguales" si una determinada variable de instancia en el objeto es igual. Entonces, asumí que la manera más fácil de hacer esto sería insertar todos mis objetos en un conjunto, y anular el método __hash__
para que tenga el hash de la variable de instancia que me preocupa.Python: detectar duplicados usando un conjunto
Por lo tanto, como una prueba He intentado lo siguiente:
class Person:
def __init__(self, n, a):
self.name = n
self.age = a
def __hash__(self):
return hash(self.name)
def __str__(self):
return "{0}:{1}".format(self.name, self.age)
myset = set()
myset.add(Person("foo", 10))
myset.add(Person("bar", 20))
myset.add(Person("baz", 30))
myset.add(Person("foo", 1000)) # try adding a duplicate
for p in myset: print(p)
Aquí, defino una clase Person
, y cualquiera de los dos casos de Person
con el mismo name
variables deben ser iguales, independientemente del valor de cualquier otra variable de instancia. Por desgracia, esto da salida:
baz:30
foo:10
bar:20
foo:1000
Tenga en cuenta que foo
aparece dos veces, por lo que este programa no se dio cuenta duplicados. Sin embargo, la expresión hash(Person("foo", 10)) == hash(Person("foo", 1000))
es True
. Entonces, ¿por qué esto no detecta correctamente los objetos duplicados Person
?
Explicación: El conjunto considera los objetos iguales si 'o1 == o2'. La función hash solo se usa para separar los objetos en los cubos de la tabla hash, por lo que solo los objetos con el mismo hash (que terminan en el mismo cubo) deben compararse para la igualdad. Así, para que funcionen 'dict' y' set' la función hash debe cumplir la condición 'x == y' =>' hash (x) == hash (y) ', pero la opuesta (' hash (x) == hash (y) '=>' x == y') nunca es verdadero. –