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!
source to share
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.
source to share
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.
source to share