tutorial tablas read que para panda libreria hacer funciones espaƱol ejemplo crear con python list set contains equality

tablas - conjunto de Python contiene vs. lista contiene



read text pandas python (2)

Estoy usando Python 2.7

considere el siguiente fragmento de código (el ejemplo es inventado):

import datetime class ScheduleData: def __init__(self, date): self.date = date def __eq__(self, other): try: return self.date == other.date except AttributeError as e: return self.date == other def __hash__(self): return hash(self.date) schedule_set = set() schedule_set.add(ScheduleData(datetime.date(2010, 8, 7))) schedule_set.add(ScheduleData(datetime.date(2010, 8, 8))) schedule_set.add(ScheduleData(datetime.date(2010, 8, 9))) print (datetime.date(2010, 8, 8) in schedule_set) schedule_list = list(schedule_set) print (datetime.date(2010, 8, 8) in schedule_list)

el resultado de esto es inesperado (para mí, al menos):

[08:02 PM toolscripts]$ python test.py True False

en el primer caso, la fecha dada se encuentra en el schedule_set ya que he anulado las funciones __hash__ y __eq__ .

desde mi punto de vista, el operador in comprobará el hash y la igualdad para los conjuntos, pero para las listas simplemente repetirá los elementos de la lista y comprobará la igualdad.

¿Entonces, Que esta pasando aquí? ¿Por qué falla mi segunda prueba para entrar in la lista schedule_list ?

¿Tengo que anular alguna otra función para las listas?


@RyanHaining es correcto. Para una solución realmente extraña, agregue este método a su clase:

def timetuple(self): return None

Entonces su programa imprimirá True dos veces. Las razones de esto están involucradas, teniendo que ver con una desafortunada historia de comparaciones en Python 2 demasiado flojo. La solución timetuple() se explica principalmente en esta parte de los documentos:

Nota: Para evitar que la comparación vuelva a caer en el esquema predeterminado de comparación de direcciones de objetos, la comparación de fecha y hora normalmente genera TypeError si la otra compañía no es también un objeto de fecha y hora. Sin embargo, NotImplemented se devuelve en su lugar si la otra comparand tiene un atributo timetuple (). Este gancho brinda a otros tipos de objetos de fecha la oportunidad de implementar una comparación de tipo mixto. De lo contrario, cuando se compara un objeto datetime con un objeto de un tipo diferente, TypeError se genera a menos que la comparación sea == o! =. Los últimos casos devuelven falso o verdadero, respectivamente.

datetime fue uno de los primeros tipos agregados a Python que intentó ofrecer un comportamiento de comparación menos sorprendente. Pero no podría convertirse en "realmente limpio" hasta Python 3.


El problema es que la comparación invoca una función __eq__ opuesta a lo que estás buscando. El método __eq__ definido funciona cuando tiene un ScheduleData() == datetime.date() pero el operador in está realizando la comparación en el orden opuesto, datetime.date() == ScheduleData() que no invoca su __eq__ definido. Solo la clase que actúa como el lado izquierdo tendrá su __eq__ llamada.

La razón por la cual este problema ocurre en python 2 y no 3 tiene que ver con la definición de datetime.date.__eq__ en la biblioteca std. Tomemos por ejemplo las siguientes dos clases:

class A(object): def __eq__(self, other): print (''A.__eq__'') return False class B(object): def __eq__(self, other): print (''B.__eq__'') items = [A()] B() in items

Al ejecutar este código, se imprime B.__eq__ en Python 2 y Python 3. El objeto B se usa como lhs, al igual que su objeto datetime.date se usa en Python 2. Sin embargo, si B.__eq__ para que se parezca a Python 3 definición de datetime.date.__eq__ :

class B(object): def __eq__(self, other): print (''First B.__eq__'') if isinstance(self, other.__class__): print (''B.__eq__'') return NotImplemented

Entonces:

First B.__eq__ A.__eq__

se imprime en Python 2 y 3. La devolución de NotImplemented causa la comprobación con los argumentos invertidos.

Usar timetuple en tu clase solucionará este problema, como dijo @TimPeters (peculiaridad interesante que desconocía), aunque parece que no necesita ser una función

class ScheduleData: timetuple = None

es todo lo que necesitarías además de lo que ya tienes.