如何在自定义排序功能中对对象的特定属性实施排序?

时间:2019-05-16 05:43:10

标签: python sorting object

我正在尝试进行快速排序以对对象的属性之一上的对象列表进行排序。 (例如2D点的对象,按x或y排序)

我有一个作业来编写quicksort和heapsort,然后在2d点列表上使用它。

快速排序:

def quick_sort(a):  # interface
    quick_sort2(a, 0, len(a)-1)


def quick_sort2(a, low, high):  # split list
    if low < high:  # stop call for list of 1
        split = partition(a, low, high)  # split index
        quick_sort2(a, low, split-1)  # left side
        quick_sort2(a, split + 1, high)  # right side


def partition(a, low, high):  # setting the pivot
    pivot_idx = get_pivot(a, low, high)
    pivot_val = a[pivot_idx]
    a[pivot_idx], a[low] = a[low], a[pivot_idx]  # swap
    border = low

    for i in range(low, high+1):  # comparing to pivot
        if a[i] < pivot_val:
            border += 1
            a[i], a[border] = a[border], a[i]
    a[low], a[border] = a[border], a[low]
    return border


def get_pivot(a, low, high):  # selecting best pivot
    middle = (high + low) // 2
    pivot = high
    if a[low] < a[middle]:
        if a[middle] < a[high]:
            pivot = middle
    elif a[low] < a[high]:
        pivot = low
    return pivot

Point2D类:

class Point2D:
    def __init__(self, id_initial: int, x_initial: float, y_initial: float):

        self.id = id_initial
        self.x = x_initial
        self.y = y_initial

    @property
    def id(self):
        return self._id

    @id.setter
    def id(self, value):
        self._id = value

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self._y = value

    def __repr__(self):
        return repr((self._id, self._x, self._y))

此行适用于sorted():

QuickSort.quick_sort(mylist, key=lambda point: point.x)

我试图为我的自定义排序功能找到解决方案, 但没有成功,请帮助我...

sorted()的代码:

mylist = []
for i in range(0, 3):
    x = random.randint(1, 10)
    y = random.randint(1, 10)
    mylist.append(Geometry.Point2D(i, x, y))

for point in mylist:
    print("P", point.id+1, "(", point.x, ",", point.y, ") ")

mylist2 = sorted(mylist, key=lambda point2d: point2d.x)

for point in mylist2:
    print("P", point.id+1, "(", point.x, ",", point.y, ") ")

输出:

P 1 ( 1 , 6 ) 
P 2 ( 9 , 9 ) 
P 3 ( 3 , 2 ) 
P 1 ( 1 , 6 ) 
P 3 ( 3 , 2 ) 
P 2 ( 9 , 9 )

2 个答案:

答案 0 :(得分:1)

如果您想使用key,则必须通过添加key参数并在每次比较列表元素时使用它来相应地修改函数(例如,{ {1}}应该是a[middle] < a[high]key(a[middle]) < key(a[high])等):

例如:

key(a[i]) < key(pivot_val)

答案 1 :(得分:0)

您需要为类Poin2D def __lt__(self,other)添加一个比较器。这样,<中的运算符getpivot()知道如何比较Point2D类的两个实例。

class Point2D:
    def __init__(self, id_initial: int, x_initial: float, y_initial: float):
        self.id = id_initial
        self.x = x_initial
        self.y = y_initial

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

[...]

之后,您可以像下面这样调用函数quicksort()

mylist = []
for i in range(0, 5):
    x = random.randint(1, 10)
    y = random.randint(1, 10)
    mylist.append(Point2D(i, x, y))

for point in mylist:
    print("P", point.id + 1, "(", point.x, ",", point.y, ") ")

quick_sort(mylist)

print('x' * 20)
for point in mylist:
    print("P", point.id + 1, "(", point.x, ",", point.y, ") ")