Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python namedtuple类上的自定义排序_Python_Sorting_Namedtuple_Functools - Fatal编程技术网

Python namedtuple类上的自定义排序

Python namedtuple类上的自定义排序,python,sorting,namedtuple,functools,Python,Sorting,Namedtuple,Functools,我经常上课。我今天一直在想,是否有一种很好的方法来实现此类的自定义排序,即使默认排序键不是namedtuple的第一个元素(然后是第二个、第三个等) 我的第一反应是实施\uu lt\uuuuuu和\uuuuu eq\uuuuuu,剩下的就让我去做(它填写了le、ne、gt、ge): 从集合导入namedtuple 从functools导入总排序 @总订单 B类(名称为双('B','x y')): 定义(自身、其他): 返回self.y

我经常上课。我今天一直在想,是否有一种很好的方法来实现此类的自定义排序,即使默认排序键不是namedtuple的第一个元素(然后是第二个、第三个等)

我的第一反应是实施
\uu lt\uuuuuu
\uuuuu eq\uuuuuu
,剩下的就让我去做(它填写了le、ne、gt、ge):

从集合导入namedtuple
从functools导入总排序
@总订单
B类(名称为双('B','x y')):
定义(自身、其他):
返回self.y
然而:

def test_sortingB():
    b1 = B(1, 2)
    b2 = B(2, 1)
    assert b2 < b1  # passes
    assert b2 <= b1  # fails
def test_sortingB():
b1=B(1,2)
b2=B(2,1)
断言b2assert b2我的建议是按照您希望字段排序的顺序创建namedtuple。您可能必须更改代码中创建值的部分(例如,将
someTuple(“name”,24)
更改为
someTuple(24,“name”)
,但通常情况下,创建值的位置比使用的位置少,因此这应该不是什么大问题。这避免了编写所有比较方法的麻烦,并且作为一个额外的好处,还避免了一直调用这些自定义比较方法所带来的额外性能开销。

选项1.使用a并应用tota我想你会同意的

@total_ordering
class B_ordering(object):
    __slots__ = ()                 # see Raymond's comment
    def __lt__(self, other):
        return self.y < other.y

class B(B_ordering, namedtuple('B', 'x y')):
    pass
@total\u排序
类别B_排序(对象):
__slots_uu=()#见雷蒙德的评论
定义(自身、其他):
返回self.y

选项2.根据
total\u排序
创建您自己的装饰器,只需使用它即可

如果,正如您的问题所暗示的,您的兴趣仅在于按备用键对名称进行排序,那么为什么不将sort/sorted
参数与
attrgetter
函数一起使用:

>>> from collections import namedtuple
>>> from operator import attrgetter
>>> P = namedtuple("P", "x y") 
>>> p1 = P(1, 2)
>>> p2 = P(2, 1)
>>> sorted([p1, p2], key=attrgetter("y"))
[P(x=2, y=1), P(x=1, y=2)]
>>> from functools import partial
>>> sortony = partial(sorted, key=attrgetter("y"))
>>> sortony([p1, p2])
[P(x=2, y=1), P(x=1, y=2)]
您可以进一步定义自己的排序函数:

>>> from collections import namedtuple
>>> from operator import attrgetter
>>> P = namedtuple("P", "x y") 
>>> p1 = P(1, 2)
>>> p2 = P(2, 1)
>>> sorted([p1, p2], key=attrgetter("y"))
[P(x=2, y=1), P(x=1, y=2)]
>>> from functools import partial
>>> sortony = partial(sorted, key=attrgetter("y"))
>>> sortony([p1, p2])
[P(x=2, y=1), P(x=1, y=2)]

你为什么不按照你想排序的顺序创建一个名元组呢?直到我已经创建了它并使用了一段时间,我才意识到我想要排序/最大化它。所以我现在可以添加一个前导字段作为排序字段,但这可能会有点混乱。但是你是如何使用名元组的呢?na的好处是medtuple允许您按名称访问项目,因此您可以更改namedtuple以使字段的顺序正确,并且不影响代码,只要您按名称访问字段(可能是这样做的,或者为什么使用namedtuple?)。是的,在访问字段时,我使用名称,但在初始化字段时通常不使用名称(请参阅我在问题第3页的评论)。排序字段还不存在,因此我需要添加它,或者使用一个cmp方法来查看2个字段并对其进行一些逻辑处理。(我的示例代码过于简化)选项1和选项2的开销是否有显著差异?+1。选项1直接解决了总排序问题,只填充缺失的值。@选项1的开销是否接近零(方法解析顺序中的一个额外步骤)。@Johnlaroy,我建议添加u slots uu=()请选择1以恢复内存效率。