Why does SortedList not have a constructor?

Question

In this exercise, the SortedList class has no constructor. Why does it not need one?

Answer

The SortedList class inherits from the Python list class. The list class provides the implementation to store data. The SortedList class doesn’t need to change the storage of data only the way that the data is added, so SortedList objects will use the constructor from the parent list class and only provide an implementation for the append() method.

5 Likes

Even though it does not need a constructor, I still added one, (shown below) because if I did not, then when I tried to instantiate an object like some_list = SortedList([1,6,3,7]), I got an error about SortedList not taking any other arguments other than self. Hence the first two lines below. I then added a line self.sort() But then when I printed (some_list.list) I got the list unsorted so I had to use the thrid line which solved that problem. I added the fourth line just to check.
def init(self, a_list):
self.list = a_list
self.list.sort()
print(self.list)

2 Likes

I created a constructor calling the super list constructor and adding sorting after it

def init(self, values):
super().init(values)
self.sort()

s_list = SortedList([4, 1, 5])
print(s_list) # returns [1, 4, 5]

3 Likes
class SortedList(list):
  def append(self, value):
    super().append(value)
    self.sort()
    
lst=SortedList([1,10,3,6,2,88,2,44,3,12])
lst.append(777)
print(lst)
#returns: [1, 2, 2, 3, 3, 6, 10, 12, 44, 88, 777]
10 Likes

Answer to following question:
When a SortedList gets initialized with unsorted values (say if you call SortedList([4, 1, 5]) ) those values don’t get sorted! How would you change SortedList so that the list is sorted right after the object gets created?

class SortedList(list):
def init(self, list):
super().init(list)
self.sort()
def append(self, value):
super().append(value)
super().sort()

ls = SortedList([9,8,4])
print (ls)

2 Likes

I had some trouble getting the syntax right but this is my contribution:

class SortedList(list):
  def __init__(self, values):
    super().__init__(values)
    self = values
    self.sort()

# add sortedlists, return sorted
  def __add__(self, other):
    self += other
    self.sort()
    return self

#append element, return sorted
  def append(self, value):
    super().append(value)
    return self.sort()

#test
lst = SortedList([4, 1, 5])
print(lst)
lst.append(8)
print(lst)
lst2 = SortedList([9, 3, 10])
print(lst2)
new = lst + lst2
print(new)
2 Likes

Why does one need to call the super method init for sorting to work? I have tried without calling the super method and it did not work

My first attempt:

def __init__(self, value):

    self.value = value

    self.value.sort()
> 
> Second attempt:
def __init__(self, value):

    super().__init__(value)

    self.value = value

    self.value.sort()

Hello and greetings from Alaska. This is my first comment, I hope I am not being a bother.
So, the reason we don’t use an def init(self): is because the primitive -list- already has one?
Thank you for your time.

Yes it’s a method that already exists in a parent class. If we don’t over override it in our new class (by defining a new .__init__ function) then the .__init__ method of the parent class is used (the list type here) which is what gives us the basic set up of the object (the values are added to the indexed and ordered mutable sequence).

A few of the examples above shows what happens if we do want to add a new behaviour to the initialisation. We want to write our own additional steps for initialisation using a newly defined __init__ method but we also still want to initialise the elements of our sequence using an iterable like the parent list class does. So what we do in that case is first call the parent classes .__init__ (using super here) and then perform any additional steps we’d like for initialisation (in this case, sorting).