1

Hi I just started learning classes in python and I'm trying to implement an array based list. This is my class and the init constructor.

class List:

def __init__(self,max_capacity=50):
    self.array=build_array(max_capacity)
    self.count=0

However, I wrote a method equals that returns true if the list equals another. However, it always return false. And yes my append method is working.

 def __eq__(self,other):
    result=False
    if self.array==other:
        result=True
    else:
        result=False
    return result

This is how I tested it but it return false?

a_list=List()
b_list=[3,2,1]
a_list.append(3)
a_list.append(2)
a_list.append(1)
print(a_list==b_list)

Any help would be appreciated!

EDIT:

After all the helpful suggestions, I figured out I have to iterate through other and a_list and check the elements.

Morse
  • 8,258
  • 7
  • 39
  • 64
Sook Lim
  • 541
  • 6
  • 28
  • What's the content of `b_list`? – Vasilis G. May 03 '18 at 15:39
  • Sorry forgot to add b_list.Edited. – Sook Lim May 03 '18 at 15:39
  • You are trying to determine if `self == other` by checking if `self.array == other`. At the very least, you probably want to compare `self.array == other.array`. `result` is an unnecessary temporary variable; just use `return self.array == other.array`. However, it's not safe to assume that `other` is also an instance of `List` just because that's the intended use case. – chepner May 03 '18 at 15:40
  • Show your append method... – Mad Physicist May 03 '18 at 15:42

2 Answers2

3

__eq__, for any class, should handle three cases:

  1. self and other are the same object
  2. self and other are compatible instances (up to duck-typing: they don't need to be instances of the same class, but should support the same interface as necessary)
  3. self and other are not comparable.

Keeping these three points in mind, define __eq__ as

def __eq__(self, other):
    if self is other:
        return True
    try:
        return self.array == other.array
    except AttributeError:
        # other doesn't have an array attribute,
        # meaning they can't be equal
        return False

Note this assumes that a List instance should compare as equal to another object as long as both objects have equal array attributes (whatever that happens to mean). If that isn't what you want, you'll have to be more specific in your question.


One final option is to fall back to other == self to see if type of other knows how to compare itself to your List class. Equality should be symmetric, so self == other and other == self should produce the same value if, indeed, the two values can be compared for equality.

except AttributeError:
    return other == self

Of course, you need to be careful that this doesn't lead to an infinite loop of List and type(other) repeatedly deferring to the other.

chepner
  • 497,756
  • 71
  • 530
  • 681
0

You are comparing the array embedded in your instance (self.array) to the entirety of the other object. This will not work well.

You need to compare self.array to other.array and/or convert both objects to the same type before comparing. You probably also need to specify what it means to compare two arrays (i.e., you want a single boolean value that indicates whether all elements are equal, not an array of boolean values for each element).

For the code below, I assume you are using a numpy ndarray for self.array. If not, you could write your own array_equal that will convert other to an array, then compare the lengths of the arrays, then return (self.array==other_as_array).all().

If you want to test for strict equality between the objects (same types, same values), you could use this:

from numpy import array_equal

import numpy as np
class List
    ...
    def __eq__(self, other):
        return isinstance(other, List) and array_equal(self.array, other.array)

If you just want to check for equality of the items in the list, regardless of the object type, then you could do this:

def __eq__(self, other):
    if isinstance(other, List):
        return array_equal(array, other.array)
    else:
        return array_equal(self.array, other)
Matthias Fripp
  • 17,670
  • 5
  • 28
  • 45