Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/366.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中,如何使用自定义键与多个值进行比较?_Python - Fatal编程技术网

在Python中,如何使用自定义键与多个值进行比较?

在Python中,如何使用自定义键与多个值进行比较?,python,Python,在实现类的\uuuuu eq\uuuu和\uuuu lt\uuuuu方法时,通常使用元组对希望比较的值进行分组,如下所示: @total_ordering class Foo(object): def __init__(self, a, b, c): self.a = a self.b = b self.c = c def __hash__(self): return hash((self.c, self.a, s

在实现类的
\uuuuu eq\uuuu
\uuuu lt\uuuuu
方法时,通常使用元组对希望比较的值进行分组,如下所示:

@total_ordering
class Foo(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def __hash__(self):
        return hash((self.c, self.a, self.b))

    def __eq__(self, other):
        return (self.c, self.a, self.b) == (other.c, other.a, other.b)

    def __lt__(self, other):
        return (self.c, self.a, self.b) < (other.c, other.a, other.b)
子类化
A
允许我定义自定义顺序,并允许
MyA
在其他方面表现得像一个普通的
A
,这很好,但这似乎是浪费/不必要的冗长,尤其是当我必须对多个字段执行此操作时

编辑:根据下面用户1320237的回答,这是我得出的结论:

@total_ordering
class Foo(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def __hash__(self):
        return hash((self.c, self.a, self.b))

    def __eq__(self, other):
        return (0, 0, 0) == (cmp(self.c, other.c),
                             cmpA(self.a, other.a),
                             cmp(self.b, other.b))

    def __lt__(self, other):
        return (0, 0, 0) > (cmp(self.c, other.c),
                            cmpA(self.a, other.a),
                            cmp(self.b, other.b))

def cmpA(a1, a2):
    # ...

(注意
\uuu lt\uuu
中的
,因为
cmp(x,y)
返回
-1
如果
x
\uu lt\uuu
应该返回
True

如果这只是一个一次性操作,下面的内容将起作用:

def custom_sorter(foo):
   """Takes Foo objects and gives a representation for sorting."""
   return (foo.c, A(foo.a), foo.b)

sorted(foo_list, key=custom_sorter)

如果要做很多次,你可以考虑一个在代码> Foo上的类方法,它是可扩展的,并吐出类似于 CuffySoRoSter < /C> >的原型。

如果您多次使用相同的自定义分类器,为什么不将其作为类的一部分呢


你只需要问问自己为什么,我真的需要这样做。

如果你想使用list.sort()进行排序,例如,你可以向它传递参数:

您的代码:

...
    def __lt__(self, other):
        return (self.c, self.a, self.b) < (other.c, other.a, other.b)

...
list.sort()
也相当于:

list.sort(key = lambda self: (self.c, self.a, self.b))
list.sort(cmp = lambda self, other: \
                (self.c, self.a, self.b) < (other.c, other.a, other.b))
list.sort(cmp=lambda self,其他:\
(self.c,self.a,self.b)<(其他c,其他a,其他b))
因此,如果你想以不同的方式对你的答案进行排序,我建议:

class Foo(object):
    @staticmethod
    def cmp_absoluteOrder(self, other):
        return (self.c, self.a, self.b) < (other.c, other.a, other.b)

    @staticmethod
    def cmp_otherOrder(self, other):
        return ...

    @staticmethod
    def cmp_combinedSort(cmpA, cmpB, cmpC):
        return lambda self, other: (0, 0, 0) < (cmpA(self.c, other.c), cmpA(self.a, other.a), cmpA(self.b, other.b), )

    def __hash__(self):
        return hash(self.c) ^ hashA(self.a) ^ hash(self.b)

...
list.sort(cmp = Foo.cmp_absoluteSorting)
list.sort(cmp = Foo.cmp_combinedSort(cmp, (lambda a1, a2: ...), cmp))

hashA = hash # or replace it if important # but the same a will retunrn the same hash
类Foo(对象):
@静力学方法
def cmp_绝对顺序(自身、其他):
返回(self.c,self.a,self.b)<(其他.c,其他.a,其他.b)
@静力学方法
def cmp_其他顺序(自身、其他):
返回。。。
@静力学方法
def cmp_组合分拣(cmpA、cmpB、cmpC):
返回lambda self,other:(0,0,0)<(cmpA(self.c,other.c),cmpA(self.a,other.a),cmpA(self.b,other.b),)
定义散列(自我):
返回哈希(self.c)^hashA(self.a)^hash(self.b)
...
list.sort(cmp=Foo.cmp\u绝对排序)
list.sort(cmp=Foo.cmp_组合排序(cmp,(lambda1,a2:…),cmp))
hashA=hash#或在重要时替换它#但相同的a将重新调用相同的hash

或者类似的东西

在您的示例中应该是
MyA(foo.a)
?如果是这样,那么将排序移到一个单独的函数中并没有帮助,因为我仍然需要自定义子类。正如您所建议的,我认为最好将排序保留在
Foo
中,而不是每次我要对一堆
Foo
进行排序时都必须将
key=…
传递到
sorted()
。它可以是您喜欢的任何东西,这是自定义的。哦,这很有趣<代码>(0,0,0)<(cmpC(…),cmpA(…),cmpB(…)
可能正是我要找的。我应该可以把它放到
中。我假设像
(0,0,0)=(…)
这样的东西应该放在
\uuuueq\uuuuuu
中,对吗?好的,看看我的编辑;我已将您的建议整合到我的代码中。现在,如果我能想出如何编写
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,我会将此标记为可接受的答案。
class Foo(object):
    @staticmethod
    def cmp_absoluteOrder(self, other):
        return (self.c, self.a, self.b) < (other.c, other.a, other.b)

    @staticmethod
    def cmp_otherOrder(self, other):
        return ...

    @staticmethod
    def cmp_combinedSort(cmpA, cmpB, cmpC):
        return lambda self, other: (0, 0, 0) < (cmpA(self.c, other.c), cmpA(self.a, other.a), cmpA(self.b, other.b), )

    def __hash__(self):
        return hash(self.c) ^ hashA(self.a) ^ hash(self.b)

...
list.sort(cmp = Foo.cmp_absoluteSorting)
list.sort(cmp = Foo.cmp_combinedSort(cmp, (lambda a1, a2: ...), cmp))

hashA = hash # or replace it if important # but the same a will retunrn the same hash