我正在尝试根据点对象的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]]
我认为我试图通过实现上述目标来交换每个实例的属性,但我不知道该怎么做。
答案 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