2016-02-29 3 views
6

Я новичок в Python. Я использую Python v2.7.Проверьте, нет ли объекта (с определенными значениями свойств) в списке

я определил простой класс Product:

class Product: 
    def __init__(self, price, height, width): 
     self.price = price 
     self.height = height 
     self.width = width 

Затем я создал список, который затем добавляется с Product объекта:

# empty list 
prod_list = [] 
# append a product to the list, all properties have value 3 
prod1 = Product(3,3,3) 
prod_list.append(prod1) 

Затем я создал еще один Product объект, который устанавливаются одинаковые значения инициализации (все 3):

prod2 = Product(3,3,3) 

Тогда, я хочу, чтобы проверить, если prod_listне содержит Product объект, который имеет цены = 3, ширина = 3 & высота = 3, путем:

if prod2 not in prod_list: 
    print("no product in list has price=3, width=3 & height=3") 

Я ожидаю, что нет распечатывают сообщение, но распечатывается. В Python, как я могу проверить, нет ли в списке объектов с определенными значениями свойств?

ответ

7

Вам необходимо добавить атрибут equality к вашему объекту. Для получения атрибутов объектов вы можете передать имена атрибутов operator.attrgetter, которые возвращают кортеж полученных атрибутов, тогда вы можете сравнить кортежи. Также вы можете использовать атрибут __dict__, который даст вам пространство имен модуля как объект словаря. Затем вы можете получить имена атрибутов, которые вы хотите сравнить с объектами на их основе.

from operator import attrgetter 

class Product: 
    def __init__(self, price, height, width): 
     self.price = price 
     self.height = height 
     self.width = width 

    def __eq__(self, val): 
     attrs = ('width', 'price', 'height') 
     return attrgetter(*attrs)(self) == attrgetter(*attrs)(val) 

    def __ne__(self, val): 
     attrs = ('width', 'price', 'height') 
     return attrgetter(*attrs)(self) != attrgetter(*attrs)(val) 

Edit:

Как @Ashwini упоминался в комментарии основано на питон вике:

Там нет подразумеваемых отношений между операторами сравнения. Правило x==y не означает, что x!=y является ложным. Соответственно, когда , определяющий __eq__(), также следует определить __ne__(), так что операторы будут вести себя так, как ожидалось.

Как более полный способ, я также добавил атрибут __ne__ к объекту. Который вернет True, если один из атрибутов не равен его относительному в другом объекте.

Демо:

prod_list = [] 
prod1 = Product(3, 3, 3) 
prod_list.append(prod1) 

prod2 = Product(3, 3, 2) 
prod_list.append(prod2) 

prod3 = Product(3, 3, 3) 
print prod3 in prod_list 
True 
prod3 = Product(3, 3, 5) 
print prod3 in prod_list 
False 
+3

** Примечание **: [Правда 'х == y' не означает, что' х = y' ложно!. Соответственно, при определении '__eq __()' следует также определить '__ne __()', чтобы операторы действовали должным образом.] (Https://docs.python.org/2/reference/datamodel.html#object. __eq__) –

+0

@AshwiniChaudhary, спасибо за отличный комментарий, но не могли бы вы показать мне, как определить '__ne __()'? Я понятия не имею об этом, хотя прочитал вашу ссылку. –

+0

@AshwiniChaudhary Действительно, спасибо за внимание. – Kasramvd

Смежные вопросы