Printing python list in subclass

I have a superclass as shown below:

class Container(object):
    """ Holds hashable objects. Objects may occur 0 or more times """
    def __init__(self):
        """ Creates a new container with no objects in it. I.e., any object 
            occurs 0 times in self. """
        self.vals = {}
    def insert(self, e):
        """ assumes e is hashable
            Increases the number times e occurs in self by 1. """
        try:
            self.vals[e] += 1
        except:
            self.vals[e] = 1
    def __str__(self):
        s = ""
        for i in sorted(self.vals.keys()):
            if self.vals[i] != 0:
                s += str(i)+":"+str(self.vals[i])+"\n"
        return s

      

And I was working on a subclass:

class Bag(Container):
    def remove(self, e):
        """ assumes e is hashable
            If e occurs in self, reduces the number of 
            times it occurs in self by 1. Otherwise does nothing. """
        # write code here
        if e in self.vals.keys():
            self.vals[e] -= 1

    def count(self, e):
        """ assumes e is hashable
            Returns the number of times e occurs in self. """
        # write code here
        if e not in self.vals.keys():
            return 0
        else:
            return self.vals[e]

    def __add__(self, other):
        new_dict = other.vals
        for e in self.vals.keys():
            if e in other.vals.keys():
                new_dict[e] += self.vals[e]
            else:
                new_dict[e] = self.vals[e]
        return new_dict

    def __str__(self):
        s1 = ""
        for i in sorted(self.new_dict.keys()):
            s1 += str(i)+":"+str(self.new_dict[i])+"\n"
        return s1

      

When running test cases:

  • a = Bag ()
  • a.insert (3)
  • a.insert (5)
  • b = Bag ()
  • b.insert (5)
  • b.insert (5)
  • b.insert (5)
  • print (a + b)

My conclusion:

{3: 1, 5: 4}

However, the expected output should be:

3: 1

5: 4

How can I get the correct output format? Thank you very much!

+3


source to share


2 answers


Currently your function is __add__

returning a normal dict instead of an instance Bag

. Instead, you can use new_dict

with a new instance Bag

and return it.

def __add__(self, other):
    new_dict = other.vals.copy()  # copy required to prevent updating `other.vals`
    for e in self.vals.keys():
        if e in other.vals.keys():
            new_dict[e] += self.vals[e]
        else:
            new_dict[e] = self.vals[e]

    # Create a new instance and populate it with new_dict
    new_instance = Bag()
    new_instance.vals.update(new_dict)
    return new_instance

def __str__(self):
    # Use self.vals here not sef.new_dict
    s1 = ""
    for i in sorted(self.vals.keys()):
        s1 += str(i)+":"+str(self.vals[i])+"\n"
    return s1

      

Demo:



>>> a + b
<__main__.Bag object at 0x1046c2470>    
>>> print(a + b)
3:1
5:4

      


You may also need the bag of statement ( collections.Counter

) data structure provided by the standard Python lib for other possible functions.

+1


source


Since after adding a

and b

you no longer have Bag

, but just a regular dict.

>>> type(a)
__main__.Bag
>>> type(b)
__main__.Bag
>>> type(a+b)
dict

      



If you want to add Bags to return another bag, you need to modify your function appropriately __add__

to return Bag

, not new_dict

what is just a regular dict.

+3


source







All Articles