【问题标题】:Using merge sort/quick sort to sort attribute of class objects in Python在 Python 中使用归并排序/快速排序对类对象的属性进行排序
【发布时间】:2020-10-02 21:58:27
【问题描述】:

我有这个学生课

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

我需要对 Student 类的一些对象进行排序,特别是使用 merge/quick sortid 进行排序,预期结果是一组学生姓名。所以如果我有这些对象:

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

以及预期的结果:

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

我不确定我需要创建对象数组或放置排序函数的位置。

有什么想法吗?

【问题讨论】:

  • 欢迎来到 SO!这有点宽泛。为什么你特别需要这些类型?内置排序函数运行 Timsort,我上次检查过,应该是最佳选择。
  • 当你说你“需要”这样做时,是为了学校作业吗?如果是这样,学校作业具体说明了什么?
  • 是的,这是对算法和数据结构的评估

标签: python arrays sorting quicksort mergesort


【解决方案1】:

将此转换为对数组,然后应用合并排序并将数组作为参数传递

def 合并(arr,l,m,r): n1 = m - l + 1 n2 = rm

# 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) 

【讨论】:

  • 这可能不是 python 的方式,因为您可以重载用于比较的运算符,例如 ">、
【解决方案2】:

您可以使用 is 创建学生列表。 假设您将自己编写归并排序函数,现在您有一个这样的函数定义:

def merge_sort(students_array)

现在应该以特定方式实现此功能,您可以根据 id 比较元素。

为此,您有几个选择:

  1. 有一个 __eq__(支持 a == b 的函数),__le__(支持 a = b 的函数),__gt__(支持 a > b 的函数),__lt__(支持 a 、=”IMO,但这些是您要考虑的功能。 Student 需要实现它们,然后可以通过比较他们的 ID 来比较两个学生 - 这可能是最 Pythonic 的方式:

示例实现:

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)

关于 python dunder 函数的好文档: https://docs.python.org/3/library/operator.html

希望有所帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 2016-01-06
    • 2019-03-07
    • 2019-07-13
    • 1970-01-01
    相关资源
    最近更新 更多