以python實現merge sort

来源:2-3 归并排序法的内存操作优化

慕用8103342

2021-12-09 14:35:50

講師你好:

以下是我以python3.9實現merge_sort的代碼,我想請問幾個問題:

1)  在以下代碼中實現泛型約束的方式是否洽當

2)  私有化構造方法的形式是法洽當

3)  目前本人正在學習python,想請問講師這樣撰寫python是否洽當 


import typing
from abc import abstractmethod, ABCMeta
from typing import Any, Protocol, List


C = typing.TypeVar("C", bound="Comparable")


class Comparable(metaclass=ABCMeta):  
    @abstractmethod
    def __eq__(self, other: Any) -> bool:
        pass

    @abstractmethod
    def __lt__(self: C, other: C) -> bool:
        pass

    def __gt__(self: C, other: C) -> bool:
        return (not self < other) and self != other

    def __le__(self: C, other: C) -> bool:
        return self < other or self == other

    def __ge__(self: C, other: C) -> bool:
        return (not self < other)


class MergeSort(object):
    __create_key = object()

    # 構造方法私有化
    @classmethod
    def create(cls, value):
        return MergeSort(cls.__create_key, value)

    def __init__(self, create_key, value):
        assert (create_key == MergeSort.__create_key), " objects must be created using MergeSort.create"
        self.value = value

    @classmethod
    def sort(cls, arr: List[Comparable]) -> None:
        temp: List = arr[::]
        cls.__sort(arr, 0, len(arr) - 1, temp)

    @classmethod
    def __sort(cls, arr: List[Comparable], start: int, end: int, temp: List[Comparable]) -> None:
        if start >= end:
            return
        mid: int = start + (end - start) // 2
        cls.__sort(arr, start, mid, temp)
        cls.__sort(arr, mid + 1, end, temp)
        if arr[mid] > arr[mid + 1]:
            cls.__merge(arr, start, mid, end, temp)

    @classmethod
    def __merge(cls, arr: List[Comparable], start: int, mid: int, end: int, temp: List[Comparable]) -> None:
        temp[start:end + 1] = arr[start:end + 1]
        i = start
        j = mid + 1
        for k in range(start, end + 1):
            if i > mid:
                arr[k] = temp[j]
                j += 1
            elif j > end:
                arr[k] = temp[i]
                i += 1
            elif temp[i] <= temp[j]:
                arr[k] = temp[i]
                i += 1
            else:
                arr[k] = temp[j]
                j += 1


写回答

1回答

liuyubobobo

2021-12-09

是否"恰当"是一个主观问题,我也不是 Python 专家。但整体,我的个人观点是:


1)

对于 Python,不需要做泛型约束。

Python 本身就是动态类型语言,首先不需要泛型。

其次,在我看来,做过多约束本身其实背离了 Python 语言的初衷。Python 就是要简单。


你可以尝试一下,对于你的代码,如果扔掉 Comparable 的约束,,排序这样一个没有定义比较相关函数的类,比如这个学生类:


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

会返回这个结果:

https://img.mukewang.com/climg/61b1b06f09c08b9318680682.jpg


核心是:Student 没有支持 > 运算。


而如果加上你设计的这个泛型支持,依然是返回这样的结果。试试看?


所以,这个约束只是从源码层面做了约束,从调用的层面,没有实际的约束(反观 Java 的泛型约束,将会让不满足类的对象在编译期间,甚至是 IDE 自身就能检测到这样的调用失败。)



2)


对于排序这个动作,我倾向于认为,不需要私有化构造函数,甚至从根子上,对于 Python 来说,不需要把算法封装在类中。Java 要这么做,是因为 Java 只支持一种设计范式:面向对象。但 Python 不是。Python 不需要所有的内容都放到对象中。所以,Python 自身的 sort,这么调用就好:


if __name__ == '__main__':
    
    students = [Student("C"), Student("B"), Student("A")]
    students = sorted(students)


没有任何的类,直接调用 sorted 方法就好。sorted 这样的函数被称为自由函数,不放在任何类中。如果需要做组织,把他们放到一个包里就好。


(比如 Python 的 math 就是这么组织的,里面是一个一个函数)



3)


再次强调,我不是 Python 专家,以上只是我的个人意见。这些内容也和算法的逻辑无关。这个课程以分析学习算法的逻辑为主,对不同语言的不同规范不做深入探讨。如果你对这方面有疑问,还请以后去相关语言的社区,或者相关语言的课程做探讨。


但是有一点需要说一下,我个人并不是很建议使用 Python 做算法的底层实现。如果你只是学习算法的逻辑,没有问题,但如果考虑上性能,那么就会有很大的问题。很有可能你辛辛苦苦实现的一个明明复杂度很优的算法,可结果其运行效率还不如一个复杂度不高的算法。比如我印象中之前试验过,使用 Python 实现一个原地的快排,其性能还不如实现一个不断开空间的非原地快排。


为什么?这是因为 Python 这类解释型语言,对解释器的依赖巨大,而不完全依赖与你的逻辑。一个理论上很费时的操作,有可能在语言内部做了优化,使得性能很快。而你自己实现的一个复杂度相同,甚至更优的算法,可能因为所有的逻辑都架在上层,反而性能很差。


所以如果你搞竞赛,使用 Python 的话,会经常发现这样的问题:完全相同的算法思路,就是因为实现的方式不同,一个多调用了一些库函数,就能通过;另一个自己从底层实现一些内容,就会超时。


那 Python 内部到底做了什么优化?答案是,Python 内部都是靠 C 实现的。


当然,这件事情也有一些解决思路,比如 pypy,但这又引出了更多的内容,全都是 Python 生态圈的事情了。但整体,暂时,Python 还是一种非常优秀的胶水语言,或者脚本语言,或者做探索性工具的语言,因为他能够快速搭建出想要的功能进行试验。但真正在底层,全部都是用 C/C++/Java 这类语言。


Python 为什么在人工智能领域火爆?就是因为人工智能领域需要大量的反复试验,所以需要能够快速搭建原型,但如果真的要做生产环境的部署,Python 绝对不是实现算法的核心语言。


著名的 Python 语言的深度学习框架 tensorflow,其源码 Python 含量只有 20%+,Python 的偶用是用于提供接口。底层全部是 C++:https://github.com/tensorflow/tensorflow


PyTorch 同理:https://github.com/pytorch/pytorch


==========


说了这么多,不是反对你用 Python 写算法,而是:


1)你以后可能会遇到 Python 实现的算法的性能问题,这是正常的;


2)我个人不是 Python 语言专家,所以非逻辑问题,不同语言的规范问题,不是这个课程的探讨范围



继续加油!:) 



0

算法与数据结构

波波老师5年集大成之作,算法与数据结构系统学习,考试、面试、竞赛通用

2610 学习 · 1087 问题

查看课程