2017-07-03 48 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)] 
相关问题