Python,按最低子对象属性对对象列表进行排序

时间:2014-04-22 14:02:31

标签: python list sorting

我正在尝试实现曲面和点的深度排序,但我不确定如何去做。 我有一个Point类,它基本上包含x,y,z坐标,它们用于定义圆的中心点,线的末端和曲面的角(tris和四边形),所以我们有:

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

class Circle(object):
    def __init__(self, center, radius):
        #center is a point
        self.point_array = [center]
        self.radius = radius

class Line(object):
    def __init__(self, pos1, pos2):
        #pos1, pos2 are points
        self.point_array = [pos1, pos2]

class Tri(object):
    def __init__(self, pos1, pos2, pos3):
        #pos's are Points
        self.point_array = [pos1, pos2, pos3]

class Quad(object):
    def __init__(self, pos1, pos2, pos3, pos4):
        #you get the idea by now...
        self.point_array = [point1, point2, point3, point4]

现在我正在剔除那些不可见的并将对象附加到列表中以绘制到屏幕上。我现在需要做的是按每个对象最低的z坐标对对象列表进行排序,但我不确定如何解决这个问题。

1 个答案:

答案 0 :(得分:3)

创建一个排序函数,提取每个对象的最低z坐标:

def lowest_z(obj):
    return min(p.z for p in obj.point_array)

sorted(list_of_objects, key=lowest_z)

您可以使用lambda函数来内联该函数,当然:

sorted(list_of_objects, key=lambda o: min(p.z for p in o.point_array))

这假设您要排序的列表中没有Point个对象,只有QuadTriLineCircle个对象。

向返回最低z坐标的对象添加方法会很有帮助;这样你可以根据物体的类型调整该点的确定方式;这样,只有半径和中心点的Cicle类仍然可以根据该信息计算出最小值z

class Shape(object):
    # subclasses must provide a point_array instance attribute
    @property
    def lowest_z(self):
        return min(p.z for p in self.point_array)

class Line(Shape):
    def __init__(self, pos1, pos2):
        #pos1, pos2 are points
        self.point_array = [pos1, pos2]

class Circle(Shape):
    def __init__(self, center, radius):
        #center is a point
        self.point_array = [center]
        self.radius = radius

    @property
    def lowest_z(self):
        return self.point_array[0].z - self.radius

# etc.

然后按point_array属性排序:

sorted(list_of_objects, key=lambda o: o.lowest_z)

或使用operator.attrgetter()

from operator import attrgetter

sorted(list_of_objects, key=attrgetter('lowest_z'))