2012-02-25 52 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。如果你想保持數據結構作爲單獨的列表,我建議這樣做。否則,如果你不介意重組它,使其更加面向對象,那麼可以像尼克說的那樣做一個更好的手指類。