Using merge sort/quick sort to sort attribute of class objects in Python

Viewed 477

I have this Student class

class Student:
    def __init__(self, name, id):
        self.name = name
        self.id = id

I need to sort some objects of from Student class spesifically using either merge/quick sort to sort the id and the expected result is array of Students' names. So in case i have these objects:

s1 = Student("Andy", 4)
s2 = Student("Bob", 3)
s3 = Student("Sophie", 2)
s4 = Student("Tony", 1)
s5 = Student("Jerry", 5)

And the expected result:

result = ["Tony", "Sophie", "Bob", "Andy", "Jerry"]

I'm not sure i need to create Array of object or where i put the Sorting function.

Any thoughts?

2 Answers

You can use is to create a list of the students. Suppose you will write the merge sort function on your own and now you have a function definition like this:

def merge_sort(students_array)

Now this function should be implemented in a specific way where you can compare elements based on the id.

To do so you have a few options:

  1. have a __eq__ (function to support a == b), __le__ (function to support a <= b), __ge__ (function to support a >= b), __gt__ (function to support a > b), __lt__ (function to support a < b). You can do with just "<, >, =" IMO but these are the functions you want to think about. Student needs to implement them, which will then be able to compare two students by comparing their ID - this is probably the most pythonic way to go:

Example Implementation:

class Student:
    def __init__(self, name, id):
        self.name = name
        self.id = id
    def __eq__(self, other):
        return self.id == other.id

    def __gt__(self, other):
        return self.id > other.id

    def __lt__(self, other):
        return self.id < other.id

...
# getting a list of Students, not only ids
def merge_sort(students_array):
...
    # example compare in the sort function
    # this will be translated to: students_array[i].__gt__(students_array[j])
    # which will return: students_array[i] > students_array[j]
    if students_array[i] > students_array[j]:
        # do something
...

def main():

    s1 = Student("Andy", 4)
    s2 = Student("Bob", 3)
    s3 = Student("Sophie", 2)
    s4 = Student("Tony", 1)
    s5 = Student("Jerry", 5)
    students_array = [s1, s2, s3, s4, s5]
    merge_sort(students_array)

Good documentation about python dunder functions: https://docs.python.org/3/library/operator.html

Hope that helped

convert this in array of pair and then apply mergersort and pass array as argument

def merge(arr, l, m, r): n1 = m - l + 1 n2 = r- m

# create temp arrays 
L = [0] * (n1) 
R = [0] * (n2) 

# Copy data to temp arrays L[] and R[] 
for i in range(0 , n1): 
    L[i] = arr[l + i] 

for j in range(0 , n2): 
    R[j] = arr[m + 1 + j] 

# Merge the temp arrays back into arr[l..r] 
i = 0    # Initial index of first subarray 
j = 0    # Initial index of second subarray 
k = l    # Initial index of merged subarray 
enter code here

while i < n1 and j < n2 : 
    if L[i][1] <= R[j][1]: // here you need to compare id
        arr[k] = L[i] 
        i += 1
    else: 
        arr[k] = R[j] 
        j += 1
    k += 1
# Copy the remaining elements of L[], if there 
# are any 
while i < n1: 
    arr[k] = L[i] 
    i += 1
    k += 1
# Copy the remaining elements of R[], if there 
# are any 
while j < n2: 
    arr[k] = R[j] 
    j += 1
    k += 1

def mergeSort(arr,l,r): 
      if l < r: 
        # Same as (l+r)//2, but avoids overflow for 
        # large l and h 
        m = (l+(r-1))//2
        # Sort first and second halves 
        mergeSort(arr, l, m) 
        mergeSort(arr, m+1, r) 
        merge(arr, l, m, r) 

arr = [( "sdas",1), ( "asd3",3), ( "asd1",2)] 
n = len(arr) 
print ("Given array is") 
for i in range(n): 
    print ("%s" %arr[i][0]), 

mergeSort(arr,0,n-1) 
print ("\n\nSorted array is") 
for i in range(n): 
    print (arr[i]), 
#or you can use predefined sort function like this
def sortSecond(val): 
    return val[1] 
arr = [( "sdas",1), ( "asd3",3), ( "asd1",2)] 
# sorts the array in ascending according to 
# second element 
arr.sort(key = sortSecond) 
print(arr) 
Related