在Python中排序对象
我想根据对象的某个属性来排序。目前,我是这样做的:
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 属性的格式是:
utility={chosenCar:25000,anotherCar:24000,yetAnotherCar:24500}
我想用 operator.attrgetter() 根据 chosenCar 的 utility 来排序。我该怎么做呢?
提前谢谢你。
3 个回答
绝对不要仅仅因为你看过的某些东西就去优化代码。随便在代码里改来改去,试图让它变得更快,这并不是一个有效的优化方法。
如果你想让代码更好,这里有一些步骤可以遵循。
- 首先,不要优化。很多时候这只是浪费时间。
- 先写一个能正常运行并且可以测试的程序。
- 确定性能指标——你需要能回答“这段代码快不快?”
- 意识到你的代码可能已经足够快了。
- 如果你不能确定第(4)步,使用工具分析你的代码,看看它在哪些地方花了时间。在Python中,你可以使用http://docs.python.org/library/profile.html来做到这一点。瓶颈往往出现在意想不到的地方,这个工具会告诉你哪些地方需要你去努力优化。
- 检查那些耗时的代码,看看是否有算法上的问题。有时候这个问题出现在你当前的代码中,但往往在更高的层次上也会出现。改善你的算法几乎总是能带来最大的速度提升。
如果你无法改善算法,可以测试不同的代码片段,看看它们的表现如何。使用http://docs.python.org/library/timeit.html来测试代码片段(这比人们想象的要复杂,所以要小心),然后重新进行性能测试和分析。
虽然可能会想在一开始就进行这个步骤,但这通常不会有好结果。你需要确保你所优化的内容是有意义的。
希望这些能帮助你理解如何加速代码(以及什么时候不需要去做)。我见过很多人试图用一些经验法则来替换代码,但我没有见过那些人写出优秀、快速的软件。优化必须是科学的,结合理论(比如计算机科学的知识)和实验(比如时间测试)。
在这个具体的例子中,我敢打赌SilentGhost的代码最终会比你的慢。当然我不能确定,但你也不能,除非你去测试一下。
(而且我觉得你不需要去测试,我认为你应该选择最清晰的方法,也就是你最初的那个。)
不,attrgetter
并不会比 lambda 更快,它其实只是另一种做同样事情的方法。
你可能是被建议使用 key
而不是 cmp
给搞混了,确实 key
会快很多,但你已经在使用 key
了。
要访问 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
模块来测试你自己数据的两种方法的性能。