2017-07-03 66 views
0

我知道如何通過屬性從this問題進行排序,其中最多的回答表明,這樣做的:Python的排序的子列表的對象屬性

someList.sort(key=lambda x: x.someAttr, reverse=True) 

,我已經看到了排序的子列表,其建議做類似的建議:

someList[i:j] = sorted(somelist[i:j]) 

但我怎麼能通過屬性排序子列表?我試過了:

someList[i:j].sort(key=lambda x: x.someAttr, reverse=True) 

但這沒有奏效。有什麼建議麼?

+2

爲什麼做一個就地排序切片(一種新的,不同的列表)在第二種情況下,用切片分配以更新第一種情況下的列表? –

+5

'someList [i:j] = sorted(somelist [i:j],key = lambda x:x.attr,reverse = True)'爲什麼不行? –

+1

@cᴏʟᴅsᴘᴇᴇᴅ我不知道排序後的()方法鍵是一個參數。如果你讓它成爲答案,我會接受。或者只是刪除,如果它太明顯。 – user3494047

回答

4

你在正確的軌道上。您可以使用sorted()對子列表進行排序,並將其分配給相同的拼接。這裏有一個例子:

>>> class Foo: 
... def __init__(self, val): 
...  self.val = val 
... def __repr__(self): 
...  return 'Foo(%d)' %self.val 
... 
>>> 
>>> x = [Foo(5), Foo(3), Foo(2), Foo(7)] 
>>> x 
[Foo(5), Foo(3), Foo(2), Foo(7)] 
>>> x[1:3] = sorted(x[1:3], key=lambda x: x.val) 
>>> x 
[Foo(5), Foo(2), Foo(3), Foo(7)] 

這已經排序了中間的兩個元素。對於您的用例,請不要忘記調用中的reverse=True關鍵字參數。


在相關說明中,someList[i:j].sort(key=lambda x: x.someAttr, reverse=True)無法按預期工作。那麼,它會對一個子列表進行排序,但是,當拼接原始列表時,最終會創建一個匿名副本並就地排序,然後丟失該排序的副本(它不會被分配給任何東西,而是被垃圾收集) 。原始列表不受影響。

2

你最後一種方法不起作用的原因是你試圖對子列表進行排序。當你這樣做:

L[1:-1].sort(...) 

你基本上創建複製子列表L[1:-1]。但是,由於您對副本進行了排序,因此沒有提及複製,新的排序列表丟失,隨後進行垃圾回收。

相反,您需要重新分配子列表的新排序值到舊子列表。例如:

>>> l = [1, 3, 2, 4, 5] 
>>> l[1:-1].sort() # Reference to sorted sublist is never saved 
>>> l # List unchanged 
[1, 3, 2, 4, 5] 
>>> l[1:-1] = sorted(l[1:-1]) # Reassign the sorted sublist to the old one 
>>> l # List is modfied 
[1, 2, 3, 4, 5] 

下面是有關更多您的具體情況的一個例子:

>>> class UserId: 
...  def __init__(self, id_number): 
...   self.id_number = id_number 
...  def __repr__(self): 
...   return 'UserId(id_number={})'.format(self.id_number) 
... 
>>> user_ids = [UserId(1), UserId(3), UserId(4), UserId(2), UserId(5)] 
>>> user_ids[1:-1] = sorted(user_ids[1:-1], key=lambda u: u.id_number, reverse=True) 
>>> user_ids 
[UserId(id_number=1), UserId(id_number=4), UserId(id_number=3), UserId(id_number=2), UserId(id_number=5)] 
相關問題