根据属性对对象进行排序

时间:2017-07-17 16:29:39

标签: python sorting

我正在尝试根据点对象的X和Y属性对点进行排序。下面的一个小例子来解释我的过程:

200 OK

但我需要一个像这样排序X的输出首先保持它们的顺序然后排序Y

class Point:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def __repr__(self):
        return '[{},{},{}]'.format(self.x, self.y, self.z)


#point instances
p1,p2,p3 = Point(7,85,5), Point(56,16,20), Point(24,3,30)

point_list = [p1,p2,p3]

def get_X(point):
    return point.x

def get_Y(point):
    return point.y

sorted_points = sorted(point_list, key = get_X)
# print(sorted_points) // [[7,85,5], [24,3,30], [56,16,20]]

sorted_points = sorted(sorted(point_list, key = get_X), key = get_Y)
# print(sorted_points) // [[24,3,30], [56,16,20], [7,85,5]]

我认为我试图通过实现上述目标来交换每个实例的属性,但我不知道该怎么做。

2 个答案:

答案 0 :(得分:2)

元组会自然地按你想要的方式排序。您可以通过向班级添加__lt__()函数来简化操作。 Sorted将使用此功能进行比较。然后,您可以轻松地依赖于元组的自然排序顺序:

class Point:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def __repr__(self):
        return '[{},{},{}]'.format(self.x, self.y, self.z)

    def __iter__(self):
        return iter((self.x, self.y, self.z))

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



#point instances
point_list = [Point(7,85,5), Point(56,16,20), Point(24,3,30), Point(7, 20, 0), Point(56,16,15)]

sorted(point_list)
# --> [[7,20,0], [7,85,5], [24,3,30], [56,16,15], [56,16,20]]

编辑:创建新积分

要通过单独组合每个点的已排序元素来创建新点,您可以解压缩点,对它们进行排序然后再次压缩它们。最好的方法是在类中添加__iter__()函数以使其可迭代,以便它可以支持zip。我在上面的代码中完成了这个。这将允许您这样做:

point_list = [Point(7,85,5), Point(56,16,20), Point(24,3,30), Point(7, 20, 0), Point(56,16,15)]
newTuples = list(zip(*[sorted(l) for l in zip(*point_list)]))
sortedPoints = [Point(*p) for p in newTuples ]

#sortedPoint => [[7,3,0], [7,16,5], [24,16,15], [56,20,20], [56,85,30]]

这也会对z值进行排序,但如果您出于某种原因需要它,它很容易改变它。

答案 1 :(得分:1)

通过按照您希望它们排序的顺序放置元组中的键元素(主值为first,次值为second),元组的排序方法将按照您希望的方式自动执行。 您需要更改的是key的值应设置为key=get_XY,其中get_XY返回x和y坐标的元组:

def get_XY(point):
    return point.x, point.y