在python类中实现合并排序函数,错误

时间:2018-06-08 06:27:59

标签: python algorithm class namespaces mergesort

所以我定义了一个函数,如果它是由寂寞实现的,它在线性数组上进行合并排序很有效,但是如果我把它放到类中就会出错。我认为这是我不太了解课程如何运作的一个很好的例子;可能在命名空间管理方面(?)。

见下文:

def sort(array):
    print('Splitting', array)
    if len(array) > 1:
        m = len(array)//2
        left = array[:m]
        right = array[m:]

        sort(left)
        sort(right)

        i = 0
        j = 0
        k = 0

        while i < len(left) and j < len(right):
            if left[i] < right[j]:
                array[k] = left[i]
                i += 1
            else:
                array[k] = right[j]
                j += 1
            k += 1

        while i < len(left):
            array[k] = left[i]
            i += 1
            k += 1

        while j < len(right):
            array[k] = right[j]
            j += 1
            k += 1
    print('Merging', array)

arr = [1,6,5,2,10,8,7,4,3,9]
sort(arr)

产生预期的正确输出:

Splitting  [1, 6, 5, 2, 10, 8, 7, 4, 3, 9]
Splitting  [1, 6, 5, 2, 10]
Splitting  [1, 6]
Splitting  [1]
Merging  [1]
Splitting  [6]
Merging  [6]
Merging  [1, 6]
Splitting  [5, 2, 10]
Splitting  [5]
Merging  [5]
Splitting  [2, 10]
Splitting  [2]
Merging  [2]
Splitting  [10]
Merging  [10]
Merging  [2, 10]
Merging  [2, 5, 10]
Merging  [1, 2, 5, 6, 10]
Splitting  [8, 7, 4, 3, 9]
Splitting  [8, 7]
Splitting  [8]
Merging  [8]
Splitting  [7]
Merging  [7]
Merging  [7, 8]
Splitting  [4, 3, 9]
Splitting  [4]
Merging  [4]
Splitting  [3, 9]
Splitting  [3]
Merging  [3]
Splitting  [9]
Merging  [9]
Merging  [3, 9]
Merging  [3, 4, 9]
Merging  [3, 4, 7, 8, 9]
Merging  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

但是,当我尝试在类中使用此函数时,我收到错误;我认为,与命名空间管理有关。见下文:

class MergeSort(object):

    def __init__(self, array):
        self.array = array

    def sort(self):
        print('Splitting', self.array)
        if len(self.array) > 1:
            m = len(self.array)//2
            left = self.array[:m]
            right = self.array[m:]

            sort(left)
            sort(right)

            i = 0
            j = 0
            k = 0

            while i < len(left) and j < len(right):
                if left[i] < right[j]:
                    self.array[k] = left[i]
                    i += 1
                else:
                    self.array[k] = right[j]
                    j += 1
                k += 1

            while i < len(left):
                self.array[k] = left[i]
                i += 1
                k += 1

            while j < len(right):
                self.array[k] = right[j]
                j += 1
                k += 1
        print('Merging', self.array)

x = MergeSort([1,6,5,2,10,8,7,4,3,9])
x.sort()

产生错误输出:

Splitting [1, 6, 5, 2, 10, 8, 7, 4, 3, 9]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-15-89509f86277e> in <module>()
      1 x = MergeSort([1,6,5,2,10,8,7,4,3,9])
----> 2 x.sort()

<ipython-input-14-2bba116f00ce> in sort(self)
     11             right = self.array[m:]
     12 
---> 13             sort(left)
     14             sort(right)
     15 

NameError: name 'sort' is not defined

我最初的本能,在谷歌搜索之后是通过添加前缀self来改变子程序sort(左)和sort(右),但是这会产生位置参数错误。我喜欢一两条关于我在这里不理解的评论。如果我的问题不是愚蠢的话,那就是为了好票而欢呼,如果是的话,还要投票。

3 个答案:

答案 0 :(得分:4)

sort(left)无效的原因是,正如您所推测的那样,您无法在self上调用方法而无需指定self。离开此意味着它会查找本地或全局名称sort,找不到该名称,并提出NameError

self.sort(left)无效的原因是您定义的API不会以这种方式工作。您的类将列表作为构造函数参数,然后使用不带参数的sort,它在构造时传递的列表上运行。因此,您无法使用不同的数组调用自己的sort。如果您尝试使用self.sort(left),则传递错误数量的参数,就像调用abs(1, 2)一样,并获得相同的TypeError

您必须按照设计方式使用API​​:使用新列表创建新的MergeSort分拣机对象,然后在该新对象上调用sort

leftsorter = MergeSort(left)
leftsorter.sort()
rightsorter = MergeSort(right)
rightsorter.sort()

答案 1 :(得分:0)

使用

替换我班级中sort()函数的sort(left)sort(right)组件
leftsorter = MergeSort(left)
leftsorter.sort()
rightsorter = MergeSort(right)
rightsorter.sort()

(谢谢abarnert)

同时从代码中删除调试打印语句(谢谢Evgany P),并避免重用内置函数名sort()以避免混淆,我有一个有效的MergeSort类。

class MergeSort(object):

    def __init__(self, array):
        self.array = array

    def merge_sort(self):
        if len(self.array) > 1:
            m = len(self.array)//2
            left = self.array[:m]
            right = self.array[m:]

            leftsorter = MergeSort(left)
            leftsorter.merge_sort()
            rightsorter = MergeSort(right)
            rightsorter.merge_sort()

            i = 0
            j = 0
            k = 0

            while i < len(left) and j < len(right):
                if left[i] < right[j]:
                    self.array[k] = left[i]
                    i += 1
                else:
                    self.array[k] = right[j]
                    j += 1
                k += 1

            while i < len(left):
                self.array[k] = left[i]
                i += 1
                k += 1

            while j < len(right):
                self.array[k] = right[j]
                j += 1
                k += 1

x = MergeSort([3,5,6,2,1,4,10,9,8,7])
x.merge_sort()
x.array

Out []:[1,2,3,4,5,6,7,8,9,10]

每个人都做得好!

答案 2 :(得分:-1)

您需要在课程中拨打self.sort()

更大的问题是你的函数或类方法都没有返回任何东西,只是打印,你满意吗?