【发布时间】:2012-09-27 04:42:33
【问题描述】:
我经常使用namedtuple 类。我今天一直在想是否有一种很好的方法可以为此类实现自定义排序,即使默认排序键不是 namedtuple 的第一个元素(然后是第二个、第三个等)。
我的第一反应是实现__lt__ 和__eq__,然后让total_ordering 完成剩下的工作(它填写了le、ne、gt、ge):
from collections import namedtuple
from functools import total_ordering
@total_ordering
class B(namedtuple('B', 'x y')):
def __lt__(self, other):
return self.y < other.y
但是:
def test_sortingB():
b1 = B(1, 2)
b2 = B(2, 1)
assert b2 < b1 # passes
assert b2 <= b1 # fails
哦,对了……total_ordering只填写了其他方法if they are missing。由于 tuple/namedtuple 有这样的方法,total_ordering 对我没有任何作用。
所以我想我的选择是
- 停止使用 namedtuple 并构建我自己的无聊类,继续使用 total_ordering
- 继续使用 namedtuple 并实现所有 6 种比较方法
- 继续使用 namedtuple 并插入一个排序值作为第一个字段。幸运的是,我没有太多的类实例,但通常我只是依靠字段的顺序来初始化它们,这可能很讨厌。也许这是一个坏习惯。
关于解决此问题的最佳方法的建议?
【问题讨论】:
-
你为什么不按照你想要排序的顺序创建namedtuple?
-
直到我创建并使用了一段时间后,我才意识到我想要对它进行排序/最大化等。所以我现在可以添加一个前导字段作为排序字段,但这可能会有点破坏性。
-
但是你是如何使用namedtuple的呢? namedtuple 的好处是它允许您按名称访问项目,因此您可以更改您的 namedtuple 以使字段按正确的顺序排列并且不会影响您的代码,只要您按名称访问字段(大概是做,否则为什么使用namedtuple?)。
-
是的,在访问字段时,我确实使用了该名称,但在初始化它们时通常不使用(请参阅我在问题#3 处的评论)。
标签: python sorting namedtuple functools