o.o
o.o

Reputation: 3751

Python checking if object member value is in list

I have this class called Point:

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

I have a list with Point objects and I call a method to check if it's in the list like this:

def isInList(self, list, point):
    for cell in list:
        if(cell == point):
            return True

    return False

However, it never goes inside the if statement; so it always returns false. I know for a fact that a point that matches has to be in the list due to a visualization I have showing up in my program. What am I doing wrong?


I call these two methods to make a list of Point. I pass cells and directions like this (called multiple times with different points and directions):

point = Point(2, 4)
direction = Direction.UP
newList = self.setCells(point, direction)

def setCells(self, point, direction):
    pointList = []
    index = 0
    done = False

    while index < 20 and done == False:
        newPoint = self.getNextCell(point, direction)

        if(point not in pointList):
            pointList.append(newPoint)
            point = pointList[len(pointList)-1]
            index += 1
        else:
            done = True

    return pointList

def getNextCell(self, point, direction):
    if(direction == Direction.UP):
        return Point(point.x-1, point.y, Direction.UP)
    elif(direction == Direction.DOWN):
        return Point(point.x+1, point.y, Direction.DOWN)
    elif(direction == Direction.LEFT):
        return Point(point.x, point.y-1, Direction.LEFT)
    elif(direction == Direction.RIGHT):
        return Point(point.x, point.y+1, Direction.RIGHT)

Direction is an enum:

class Direction(Enum):
    NONE = 1
    UP = 2
    DOWN = 3
    LEFT = 4
    RIGHT = 5

Upvotes: 0

Views: 148

Answers (2)

Jonathan von Schroeder
Jonathan von Schroeder

Reputation: 1703

Unfortunately the code from the OP's question seems to contain functions that were meant to be bound to an object (setCells and getNextCell), but are exhibited without their class. Furthermore the call to the constructor of Point in getNextCells had an additional argument (the direction), which I removed. Therefore I am considering the following code:

import enum

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

def setCells(point, direction):
    pointList = []
    index = 0
    done = False

    while index < 20 and done == False:
        newPoint = getNextCell(point, direction)

        if(point not in pointList):
            pointList.append(newPoint)
            point = pointList[len(pointList)-1]
            index += 1
        else:
            done = True

    return pointList

class Direction(enum.Enum):
    NONE = 1
    UP = 2
    DOWN = 3
    LEFT = 4
    RIGHT = 5

def getNextCell(point, direction):
    if(direction == Direction.UP):
        return Point(point.x-1, point.y)
    elif(direction == Direction.DOWN):
        return Point(point.x+1, point.y)
    elif(direction == Direction.LEFT):
        return Point(point.x, point.y-1)
    elif(direction == Direction.RIGHT):
        return Point(point.x, point.y+1)

point = Point(2, 4)
direction = Direction.UP
newList = setCells(point, direction)
print(point in newList)

which prints False. To investigate if this is correct it is useful to add some pretty printing to the class Point:

def __repr__(self):
    return "Point(%s,%s)" % (self.x,self.y)

It is now possible to easily investigate the contents of the list:

>>> print(newList)
[Point(1,4)]
>>> print(point)
Point(2,4)

Since newList contains only one point which has a different x-coordinate it is obvious that point in newList should be false.

To better understand why newList does not contain point it is useful to give a simplified version of setCells:

def setCellsSimplified(point,direction):
    return [getNextCell(point, direction)]

Explanation: Initially pointList is empty, so point not in pointList will be true regardless of the value of point. Thus newPoint is added to pointList and point is now equal to newPoint. Therefore, when the while-body runs again, point is in pointList and the second execution is the last execution of the while-body.

Since getNextCell always returns a new Point that differs in one coordinate from the object passed to it point and getNextCell(point,dir) are never equal (regardless of the direction) and therefore point in setCells(point,dir) is always false (which can be seen easily by looking at the simplified version setCellsSimplified).

Upvotes: 1

Geoff
Geoff

Reputation: 11

I'm confused my how you are invoking this. Your function takes in self, list, and point. If this is a method of an object, and you want to see if the current object is in the list I would try something like this instead...

    def isInList(self, list):
        return self in list

That should give you an output similar to this...

>>> list = [Point(2,2), Point(3,3), Point(4,4)]
>>> x = Point(4,4)
>>> x.isInList(list)
True
>>> x = Point(4,5)
>>> x.isInList(list)
False

Upvotes: 0

Related Questions