2012-02-25 46 views
2

我有一个对象大致像这样:如何排序对象属性

class Hand(object): 
    def __init__(self, finger_names, finger_lengths, nail_sizes): 
     self.finger_names = finger_names 
     self.finger_lengths = finger_lengths 
     self.nail_sizes = nail_sizes 

    def _sort_by_finger_lengths(self): 
     ???? 

finger_namesfinger_lengthsnail_sizes都是要么同样长的列表或空(例如,如果人没有测量他们的nail_sizes但)。目标是通过finger_lengths对对象的属性进行排序。所以如果你从一个Hand对象开始,其中的列表按照从左到右的顺序排列(小指,圆环,中间,指针,拇指),你最终会得到一个Hand对象,其中所有的属性都由finger_lengths排序。

像这样:

finger_names = [pinky, thumb, pointer, ring, middle] 
finger_lengths = [6, 7, 12, 13, 15] 
nail_sizes = [] 

编辑补充:手仅仅是一个例子类。真正的代码有很好的理由让每个属性都有列表。

+3

我真的很感兴趣的手指定长度的图片... – 2012-02-25 20:51:23

+4

您的数据结构是错误的。你需要有一个单一的列表,其中的每个项目有3个属性,fingerName,fingerLength和nailSize。然后,当您排序时,所有关联的属性都保留在一起。或者你有一个以fingerName作为关键字的字典。但保留一根手指的所有属性。 – 2012-02-25 20:51:42

+0

@DavidHeffernan你说得对 - 这只是一个例子。我的真实数据更复杂。 – mlissner 2012-02-25 21:18:45

回答

0

一个简单的方法是这样:

>>> finger_names, finger_lengths 
(('pointer', 'ring', 'pinky', 'middle', 'thumb'), (12, 13, 6, 15, 7)) 
>>> s_tuples = sorted(zip(finger_names, finger_lengths), key=lambda x: x[1]) 
>>> finger_names, finger_lengths = zip(*s_tuples) 
>>> finger_names, finger_lengths 
(('pinky', 'thumb', 'pointer', 'ring', 'middle'), (6, 7, 12, 13, 15)) 

然而,Nick是不是根据它们的顺序将它们联系起来的正确的,你应该为在一个数据结构链接这些。

上述策略(使用key)在这种情况下仍然有效,但您不需要使用zip(*s_tuples)将它们关联。

另一方面,如果你想解除它们之间的关系,那么以前我就忘记了一种单线解决方案。

finger_lengths, finger_names = zip(*sorted(zip(finger_lengths, finger_names))) 

或者,如果你想在地方进行排序,节省了一个复制操作:

s_tuples = zip(finger_lengths, finger_names) 
s_tuples.sort() 
finger_lengths, finger_names = zip(*temp) 
3

任何数量的人都可以告诉你如何做到这一点,但它似乎很脆弱。为什么不做一个Finger课,并保存自己的一些理智?

class Finger(object): 
    PINKY = 0 
    RING = 1 
    MIDDLE = 2 
    INDEX = 3 
    THUMB = 4 

    def __init__ (self, type): 
    self.type = type 
    self.length = None 
    self.nail_size = None 

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

f = Finger(Finger.PINKY) 
f.length = 6 

这是既容易在任一方向进行排序,你不必担心错位,其中手指报道长度和不。

+0

对不起 - 应该明确这只是一个示例类。真正的代码更棘手。 – mlissner 2012-02-25 21:23:05

+0

@mlissner:很难判断一个人应该如何使用示例代码来做到这一点,而这些代码实际上并不像真正的代码。:-)我会特别感兴趣的是任何有“理由”的类都具有相同的尺寸但单独的名单。 – 2012-02-25 21:33:42

0

你可以使用所有的三个属性的元组单列表排序过程中,让他们在一起。一个简单的方法使用现有的数据结构的排序代码要做到这一点是使用zip他们像这样

l = zip(finger_lengths, finger_names, nail_sizes) 
l.sort() 
finger_lengths, finger_names, nail_sizes = zip(*l) 

如果你的指甲大小是空的,虽然这并不工作相结合,并解压,所以即使有没有什么东西你应该填入零可能像nail_sizes = [0] * 5。如果你想保持数据结构作为单独的列表,我建议这样做。否则,如果你不介意重组它,使其更加面向对象,那么可以像尼克说的那样做一个更好的手指类。