Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if an object (with certain properties values) not in list

I am new in Python. I am using Python v2.7.

I have defined a simple class Product:

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

Then, I created a list, which is then appended with a Product object:

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

Then, I created another Product object which is set the same initialize values (all 3):

prod2 = Product(3,3,3)

Then, I want to check if prod_list doesn't contain a Product object that has price=3, width=3 & height=3, by:

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

I expect there is no print out message, but it is printed out. In Python, how can I check if a list doesn't have an object with certain property values then?

like image 534
Leem.fin Avatar asked Feb 29 '16 08:02

Leem.fin


1 Answers

You need to add an equality attribute to your object. For getting the objects attributes you can pass the attribute names to operator.attrgetter which returns a tuple of gotten attributes then you can compare the tuples. Also you can use __dict__ attribute which will gives you the module’s namespace as a dictionary object. Then you can get the attributes names which you want to compare the objects based on them.

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:

As @Ashwini mentioned in comment based on python wiki:

There are no implied relationships among the comparison operators. The truth of x==y does not imply that x!=y is false. Accordingly, when defining __eq__(), one should also define __ne__() so that the operators will behave as expected.

So as a more comprehensive way I also added the __ne__ attribute to the object. Which will return True if one of the attributes is not equal to it's relative one in other object.

Demo:

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
like image 92
Mazdak Avatar answered Sep 21 '22 22:09

Mazdak