2009-12-17 42 views
0

我是新來的Python填單子,因此在使用時的錯誤術語:)對象和排序(新手)

時,我想有幾個「對象」的名單原諒我,他們每個人具有相同的數字屬性(A,B,C)。然後這個列表應該按屬性A的值排序。

在Java中,我將定義一個類,其中我的屬性作爲成員,實現Sortable來比較A,將它們全部放在某種列表中並讓Collections.sort排序名單。

結果應該「看」這樣的:

A B C 
1 2 3 
1 2 4 
2 5 1 
3 1 1 

什麼是做這樣的事情在Python中的最佳方式?

+0

,該清單應當由值A進行排序,但是你的例子似乎表明,它應該再被B排序,然後是C?或者這只是巧合? – truppo 2009-12-17 09:08:32

+0

對不起,這只是巧合。分類時忽略B和C. – 2009-12-17 09:10:31

回答

6
class myclass(object): 
    def __init__(self, a, b, c): 
     self.a = a 
     self.b = b 
     self.c = c 

    def __repr__(self): 
     return "(a=%s, b=%s, c=%s)" % (self.a, self.b, self.c) 

>>> obj1 = myclass(1, 2, 3) 
>>> obj2 = myclass(1, 2, 4) 
>>> obj3 = myclass(2, 5, 1) 
>>> obj4 = myclass(3, 1, 1) 

>>> print sorted([obj1, obj2, obj3, obj4], key=lambda o: o.a) 
[(a=1, b=2, c=3), (a=1, b=2, c=4), (a=2, b=5, c=1), (a=3, b=1, c=1)] 
+0

會幫助示例在'__repr__'中使用'「(a =%s,b =%s,c =%s)」',並將初始列表放入非排序順序以顯示sorted()實際上一些東西。 – 2009-12-17 09:26:14

+0

@Roger Pate:好點。編輯。 – 2009-12-17 09:28:47

4

對不起,如果我把你的問題錯誤的方式。我不太清楚。

所以,我會認爲像你想的列進行排序

比方說,x是2維數組

>>> x=[[1, 2, 3], [1, 2, 4], [2, 5, 1], [3, 1, 1]] 
>>> x 
[[1, 2, 3], [1, 2, 4], [2, 5, 1], [3, 1, 1]] 

這裏是做每一列進行排序的一種方法,使用itemgetter

from operator import itemgetter 

>>> sorted(x,key=itemgetter(0)) 
[[1, 2, 4], [1, 2, 3], [2, 5, 1], [3, 1, 1]] 
>>> sorted(x,key=itemgetter(1)) 
[[3, 1, 1], [1, 2, 4], [1, 2, 3], [2, 5, 1]] 
>>> sorted(x,key=itemgetter(2)) 
[[3, 1, 1], [2, 5, 1], [1, 2, 3], [1, 2, 4]] 

如果你想就地分揀,請像x.sort(key=itemgetter(0))

+0

-1不回答問題。 OP特別要求一種方法來排序具有屬性A,B和C的**對象**;沒有3件物品的清單。 – 2009-12-17 19:55:40

2
List = [(3,1,1),(1,2,4),(2,5,1),(1,2,3)] 
sorted(List) 

更新:答案的核心實際上是內置的sorted。我只是把它放在兩行,以允許增量檢查,(a)所選的數據結構是元組列表,並且(b)排序由sorted完成。正如一位評論者指出的那樣,排序()將一次按A排序,然後是B,然後是C(無論這是否需要)。其他答案提供了一個很好的關於在調用sorted()時添加一個key-picking函數來確定哪個元素將用於比較。再次,這是否有利是OP的判斷。我想提供一個最小的解決方案。

Update1:​​我將列表中的元素進行了混洗,因此它更多地處理排序:)。

+0

按A然後B然後C排序,而S.Mark只按A排序,實際上在排序時會忽略B和C.如果這個更簡單的解決方案是可以接受的,OP對我來說還不清楚。 – 2009-12-17 10:29:59

+0

我把OP的「忽略」看成「我不在乎」,所以沒有實際忽略它們對我來說不是問題。問題是結果看起來與輸入相同,所以如果你不知道它,不可能告訴sorted()做了些什麼,並且忽略了(如何在B上排序的強烈暗示的,恕我直言)的問題,或者C而不是A?「我很喜歡只用代碼來回答一個問題,但是這個答案並沒有成立,需要解釋。 – 2009-12-17 17:26:51

+0

-1不回答問題。 OP特別要求一種方法來對具有屬性A,B和C的對象進行排序;沒有3件物品的清單。 – 2009-12-17 19:59:15

2

你可以給比較功能列表的sort的第一個參數請參見下面的代碼:

class Foo: 
    def __init__(self, a, b=0, c=0): 
     self.a = a 
     self.b = b 
     self.c = c 

    def __repr__(self): 
     return "%d %d %d" % (self.a, self.b, self.c) 


foos = [Foo(2, 5, 1), Foo(1, 2, 4), Foo(3, 1, 1), Foo(1, 2, 3)] 

def cmp_a(f1, f2): 
    if f1.a == f2.a: 
     return 0 
    elif f1.a < f2.a: 
     return -1 
    else: 
     return 1 

foos.sort(cmp_a) 

for f in foos: 
    print f 
+0

雖然正確並有效,但似乎'cmp'函數正在逐漸淘汰,至少在Python中是優先於'關鍵'函數。 – 2009-12-17 17:22:45

3

考慮使用namedtuple來創建你的對象。 (看一看is-there-a-tuple-data-structure-in-python。)

collections.namedtuple(typename, field_names[, verbose])

返回一個新的命名類型名的元組的子類。新的子類用於創建具有可通過屬性查找訪問的字段的類似元組的對象,以及可索引和可​​迭代的對象。子類的實例也有一個有用的文檔字符串(帶有typename和field_names)和一個有用的方法,它以name = value格式列出元組內容。

A B C字段名稱的簡單交互式會話。排序是直接與 key=lambda o:o.A:你是說

>>> import collections 
>>> mob=collections.namedtuple('myobj',('A','B','C')) 
>>> mlist = [mob(3,1,1), mob(1,2,3), mob(1,2,4), mob(2,5,1)] 
>>> mlist 
[myobj(A=3, B=1, C=1), myobj(A=1, B=2, C=3), myobj(A=1, B=2, C=4), myobj(A=2, B=5, C=1)] 
>>> for x in sorted(mlist,key=lambda o:o.A): 
...  print x 
...  
myobj(A=1, B=2, C=3) 
myobj(A=1, B=2, C=4) 
myobj(A=2, B=5, C=1) 
myobj(A=3, B=1, C=1) 
>>>