有没有可能重新定义元组的相等运算符?

2024-10-01 07:51:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些用元组表示边的代码

(vertex_1, vertex_2)

我有代表平面嵌入面的边的列表,例如下面的例子。在

我需要搜索列表中是否存在边,但是如果使用(v1, v2)(v2, v1),我需要返回true:

^{pr2}$

Tags: 代码true列表代表例子v2元组vertex
3条回答

"Is it possible to redefine the equal operator for tuples"

差不多吧。不能在基本tuple类型上执行此操作,但可以在子类上执行此操作:

 class MyTuple(tuple):
     def __eq__(self, other):
         orig_eq = super(MyTuple, self).__eq__(other)
         if orig_eq and orig_eq is not NotImplemented:
             return True
         else:
             return super(MyTuple, self).__eq__(other[::-1])

一般来说,这可能不是最好的方法。根据问题的限制条件,您可以尝试一组冻结集:

^{pr2}$

这里的优点是,如果您对同一数据执行多个成员身份测试,您可能会获得更好的运行时间(列表中的每个成员身份测试都是O(N),您需要为每个要检查的项执行最多两个,而您只需要一个O(N)步骤来构建f1_set,然后每个成员资格测试都是O(1))。在

您不能重写现有类型的equality方法,因此必须创建自己的类型,然后要求您用自定义类型替换所有现有元组。在

如果您的主要问题只是(6,1) in f1用例,那么也许您应该考虑为此创建一个方法:

def contains(t, lst):
    return (t[0], t[1]) in lst or (t[1], t[0]) in lst

然后你就可以这样使用它:

^{pr2}$

这样做的好处是,您不需要用不同的类型替换元组。因此,您可以按原样处理所有数据源。在

您应该创建一个tuple子类并更改它的相等方法(__eq__):

class UnorderedTuple(tuple):
    def __eq__(self, other):
        return len(self) == len(other) and set(self) == set(other)

适用于您的情况(tuple length==2,如果元组元素是散列的-这是不可变的,并且有一个定义良好的比较)

要将元组列表转换为无序元组列表,请执行以下操作:

^{pr2}$

要对列表进行正确的包含查询(使用in运算符)可能会很慢,因此最好使用集合而不是列表:

set_f1 =  { UnorderedTuple(f_) for f_ in f1 }
(6,1) in set_f1
(1,6) in set_f1

这个实现的性能不是很好,因为它为每个比较创建一个新的set。因此,如果元组总是f两个元素,那么将__eq__方法取消制冷会更有效,如下所示:

    def __eq__(self, other):
        return super(UnordoredTuple, self).__eq__(other) or (self[0] == other[1] and self[1] == other[0])

相关问题 更多 >