你如何让一个对象在python中返回一个排序数组而不是一个空数组?

时间:2011-12-28 22:00:18

标签: python arrays sorting

我正在尝试创建一些常用算法库,以便人们可以轻松使用它们。我创建了一个名为Compare的对象,它有一些在这些算法中很有用的方法。

比较代码:

class Compare(list):
    def __init__(self,arr):
         self.arr = arr

    def __compare(self,u,v):
        # Compares one item of a Compare
        # object to another
        if u < v:
            return 1
        if u == v:
            return 0
        if u > v:
            return -1

    def __swap(self,arr,i,j):
        # Exchanges i and j 
        temp = arr[i]
        arr[i] = arr[j]
        a[j] = temp

    def __determine(self,arr):
        # Determines if the array is sorted or not
        for i in range(0,len(array)):
            if self.__compare(arr[i], arr[i+1]) == -1:
                return False
        return True

    def __printout(self,arr):
        for i in range(0,len(array)):
            return arr[i] + '\n'

    def sorted(self):
        if self.__determine(arr):
            return True
        return False

以下是使用此类的算法之一:

    def SelectionSort(array):
        try:
            array = Compare(array)
            for ix in range(0, len(array)):
                m = ix
                j = ix+1
                for j in range(0,len(array)):
                    if array.__compare(array[j], array[m]) == -1:
                         m = j
                array.__swap(arr, ix, m)
            return array
        except(TypeError) as error:
            print "Must insert array for sort to work."

我遇到的问题是每当我尝试使用这个或任何其他算法时,它会返回一个空数组而不是排序数组。我不知道如何让Compare对象返回已排序的数组。

3 个答案:

答案 0 :(得分:1)

我很确定这就是正在发生的事情。当你打电话:

array = Compare(array)

您覆盖对原始数组的引用。 Array现在是对Compare对象的引用。用array.arr替换数组(或更好地命名数组),这应该可行! :)

请记住,python是松散类型的,所以你的“数组”变量只是对某些数据的引用。在这种情况下,您将它从对列表的引用切换为对Compare对象的引用。

想一想:

>>> x = 1
>>> x
1
>>> x = 's'
>>> x
's'

考虑一下发生了什么;)

答案 1 :(得分:1)

您的代码存在许多问题,其中一些问题导致其失败 例如

  • 在排序中,您使用的是可能不存在的全局arr self.arr)。
  • 在交换中你也使用a[j] = temp,但是a是本地方法而你不用它做任何事情
  • 您正在为方法使用两个下划线。这会使名称修改工作,因此函数中的调用不会像你那样工作。可能你想要一个下划线来表示这是私有方法。

但主要问题是比较不是一个列表。为此你需要:

class Compare(list):
    def __init__(self, arr):
        list.__init__(self, arr)

然后:

>>> print Compare([1,2,3,4])
[1, 2, 3, 4]

通过这种方式,您应该在方法self而不是self.arr中使用,因为您的实例是一个列表(或列表的子类的实例)。

以下是您修改的代码实际工作。唯一的问题是你的排序算法是错误的,它没有正确排序。但你可以从这里做到我想:

class Compare(list):
    def __init__(self, arr):
        list.__init__(self, arr)

    def _compare(self, u, v):
        # Compares one item of a Compare
        # object to another
        if u < v:
            return 1
        if u == v:
            return 0
        if u > v:
            return -1

    def _swap(self, i, j):
        # Exchanges i and j 
        temp = self[i]
        self[i] = self[j]
        self[j] = temp

    def _determine(self):
        # Determines if the array is sorted or not
        for i in range(len(array)):
            if self._compare(self[i], self[i+1]) == -1:
                return False
        return True

    def _printout(self):
        for i in self:
            return i + '\n'

    def sorted(self):
        if self._determine():
            return True
        return False


def SelectionSort(array):
    try:
        array = Compare(array)
        for ix in range(len(array)):
            m = ix
            j = ix + 1
            for j in range(len(array)):
                if array._compare(array[j], array[m]) == -1:
                    m = j
            array._swap(ix, m)
        return array
    except(TypeError) as error:
        print "Must insert array for sort to work."

答案 2 :(得分:0)

你没有返回数组,你返回一个缠绕在数组中的Compare。如果您希望Compare成为代理,则包装不完整,因为您不将标准container operations转发到代理数组。此外,您需要始终使用Compare实例。目前,您有时使用Compare,有时使用原始序列对象,例如将序列传递给方法的每个位置。相反,在自己的方法中使用Compare对象。

然而,那是Comparetwo things:是一个算法集合,并且是一个序列。如果将Compare对象分开并直接在列表上工作,则可以轻松切换算法。这是更典型的方法; list.sort以这种方式工作,以比较器为参数。您还需要修复Compare的实现,当局部变量名为array时,arr在许多地方使用错误的变量名称Compare。如果你想让任何人使用你的库,那么它的设计必须更好。

作为不使Compare成为序列的进一步理由,请考虑当您需要更改比较方法时会发生什么:最终将Compare包装在另一个中,使得包裹的SelectionSort无用。

考虑数学中使用的方法:顺序是在集合上定义的关系,而不是集合的固有部分,它尤其不是集合中项目序列的一部分。这揭示了原始方法的另一个概念错误:它将一个排序(这是一个集合关系)与对集合中元素序列的操作相结合。这两者应该分开,这样你就可以对序列操作进行不同的比较。

题外话

代码中存在许多其他类型的错误。例如,在array中,您认为类型错误必须是由于非序列传递为Compare.sorted。比较不可比较类型的实例(例如0和'd')也会导致类型错误。再举一个例子,if test: return True return False 没用;这是模式:

return test

这在逻辑上等同于:

Compare.sorted

表示Compare.__determine相当于sorted。将后者设为前者,因为{{1}}是更具描述性的名称。 “确定”太模糊了;它引出了什么是决定的问题。

您可以在codereview.stackexchange.com获得更多代码评论。