在Python中对对象进行排序

3

我想按照对象的某个属性对它们进行排序。目前,我是按照以下方式进行的:

USpeople.sort(key=lambda person: person.utility[chosenCar],reverse=True)

这段代码的功能正常,但是有人建议使用operator.attrgetter()可能会更快地实现排序。首先,这种说法正确吗?如果正确,我应该如何使用operator.attrgetter()实现这种排序?
我尝试了以下方法:
 keyFunc=operator.attrgetter('utility[chosenCar]')
 USpeople.sort(key=keyFunc,reverse=True)

然而,我遇到了一个错误,提示没有属性'utility[chosenCar]'。

问题在于我想要排序的属性在一个字典中。例如,实用属性的形式如下:

utility={chosenCar:25000,anotherCar:24000,yetAnotherCar:24500}

我想使用operator.attrgetter()根据所选车辆的效用进行排序。我该怎么做?
提前致谢。
3个回答

2

不,attrgetter 不会比 lambda 更快 - 它只是另一种做同样事情的方式。

你可能被建议使用 key 而不是 cmp 所困惑,后者确实更快,但你已经在使用 key 了。


attrgetter比lambda更快,因为它是用C实现的。但根据我的测试,差异只有约15%。 - interjay

1
要访问chosenCar项目,你需要使用以下代码:
>>> P.utility={'chosenCar':25000,'anotherCar':24000,'yetAnotherCar':24500}
>>> operator.itemgetter('chosenCar')(operator.attrgetter('utility')(P))
25000

对于 key 函数,您需要执行以下操作:

>>> def keyfunc(P):
    util = operator.attrgetter('utility')(P)
    return operator.itemgetter('chosenCar')(util)

>>> USpeople.sort(key=keyfunc,reverse=True)

然而,你关于这种方法性能更好的主张似乎研究不足。我建议使用timeit模块来测试你自己数据的两种方法的性能。


感谢您指出速度不会提高。但是,我想了解一下您使用operator.attrgetter的解决方案,以备将来之需。我拥有的人员对象都在一个列表中,例如: people=[P1,P2,P3,P4] 其中P1、P2、P3、P4都是人员。 我想使用attrgetter对其进行排序。请问在您第二行代码中的(P)的位置应该写什么? 谢谢。 - Curious2learn
1
当然,operator.attrgetter('utility')(P) 只是一种愚蠢的写法,等同于 P.utility。使用 operator.attrgetteroperator.itemgetter 的原因是可以直接使用它们。如果你要编写自己的键函数,那么它只需是 return P.utility['chosenCar'],就像最初的 lambda 函数一样。 - Thomas Wouters

1
  • 永远不要基于你读到的东西进行优化。从你已有的代码中随意更改,以便让它变得更快,并不是一种有效的优化策略。

  • 如果你想优化你的代码,以下是如何做:

    1. 不要优化。这通常是浪费时间。
    2. 制作一个可工作、可测试的程序。
    3. 确定性能指标——能够回答“这段代码足够快吗?”
    4. 认识到你的代码已经足够快了。
    5. 如果你无法完成第四步,请对你的代码进行实际输入的分析,以确定它花费时间的位置。在 Python 中,你可以使用 http://docs.python.org/library/profile.html 来完成这个任务。瓶颈出现在意想不到的地方,这将告诉你你真正需要努力的地方。
    6. 检查耗时的代码是否存在算法上的亚优化。这有时会发生在你所处的层次,但通常也会发生在几个层次之外。改进你的算法几乎总是获得加速的最大机会。
    7. 如果你无法改进你的算法,请测试执行相同任务的各个代码片段,并查看它们的性能表现。使用 http://docs.python.org/library/timeit.html 来测试片段(这比人们意识到的要困难得多,所以要小心),重新运行你的性能测试和分析。

      尝试在前期完成此步骤可能很诱人,但这通常是不会有成果的。你需要知道你正在优化的东西是有意义的。

    我希望这提供了一些关于如何加速你的代码(以及何时不必费心)的见解。我见过很多人试图用经验法则优化随机代码,但我没有看到这些人生产出伟大、快速的软件。优化必须科学地进行,使用理论(例如计算机科学中的第6点)和实验(例如第7点中的时间测量)。

  • 在这种特定情况下,我敢打赌 SilentGhost 的代码最终比你的慢。当然,我不能确定,但你也不能确定,除非你计时它。

    (我认为你不应该费心计时它,我认为你应该采用最清晰的方法,即你原来的方法。)


谢谢你的评论。在我提出问题后,我对我的代码进行了分析,发现了占用大部分时间的函数。我会考虑是否可以使用更好的算法。如果不能,我会回到stackoverflow寻求任何想法。 - Curious2learn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接