我知道如何根据this问题中的一个属性进行排序,其中最佳答案建议:
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)
但这不起作用。有什么建议吗?
答案 0 :(得分: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)
无法按预期工作。好吧,它会对子列表进行排序,但是,当您拼接原始列表时,最终会创建一个匿名副本并就地排序,然后丢失该排序副本(它没有分配给任何东西,它是垃圾收集的) 。原始列表不受影响。
答案 1 :(得分: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)]