使用 namedtuple 的部分属性进行比较
Use partial attributes from namedtuple for comparison
我有一个带字段 (x, y, z) 的命名元组,其中 z 是可选的。
像'in'这样的比较运算符会考虑所有字段进行比较
from collections import namedtuple
p = namedtuple('p' , ('x' ,'y', 'z'), defaults = (None,) * 3)
a = p(1,2, 0)
b = p(2,1)
co_ord_list = [a,b]
c = p(1,2)
if c in co_ord_list :
print(f"Already Exists")
else :
co_ord_list.append(c)
print(co_ord_list)
我不希望 'c' 在匹配 'x' 并且 'y' 已经存在时被添加到列表中。
实际输出:[p(x=1, y=2, z=0), p(x=2, y=1, z=None), p(x=1, y =2, z=None)]
预期输出:已经存在
你可以很容易地通过扩展命名元组和覆盖方法来做到这一点 __eq__
class p(namedtuple('p' , ('x' ,'y', 'z'), defaults = (None,) * 3)):
def __eq__(self, other):
return isinstance(other, self.__class__) and self.x == other.x and self.y == other.y
def __hash__(self):
return hash((x, y))
a = p(1,2, 0)
b = p(2,1)
co_ord_list = [a,b]
c = p(1,2)
if c in co_ord_list :
print(f"Already Exists")
else :
co_ord_list.append(c)
print(co_ord_list)
输出:
Already Exists
[p(x=1, y=2, z=0), p(x=2, y=1, z=None)]
您的示例可以在不定义您自己的 hash
函数的情况下工作,但这是一个很好的做法,因为 a == b
意味着 hash(a) == hash(b)
。在 __eq__
方法的条件下,它也可以在没有 isinstance(other, self.__class__)
的情况下工作,但这可以防止 AttributeError
在比较不同类型的对象时发生这种情况,如果你的列表 co_ord_list
也包含对象一些其他类型。
我有一个带字段 (x, y, z) 的命名元组,其中 z 是可选的。
像'in'这样的比较运算符会考虑所有字段进行比较
from collections import namedtuple
p = namedtuple('p' , ('x' ,'y', 'z'), defaults = (None,) * 3)
a = p(1,2, 0)
b = p(2,1)
co_ord_list = [a,b]
c = p(1,2)
if c in co_ord_list :
print(f"Already Exists")
else :
co_ord_list.append(c)
print(co_ord_list)
我不希望 'c' 在匹配 'x' 并且 'y' 已经存在时被添加到列表中。
实际输出:[p(x=1, y=2, z=0), p(x=2, y=1, z=None), p(x=1, y =2, z=None)]
预期输出:已经存在
你可以很容易地通过扩展命名元组和覆盖方法来做到这一点 __eq__
class p(namedtuple('p' , ('x' ,'y', 'z'), defaults = (None,) * 3)):
def __eq__(self, other):
return isinstance(other, self.__class__) and self.x == other.x and self.y == other.y
def __hash__(self):
return hash((x, y))
a = p(1,2, 0)
b = p(2,1)
co_ord_list = [a,b]
c = p(1,2)
if c in co_ord_list :
print(f"Already Exists")
else :
co_ord_list.append(c)
print(co_ord_list)
输出:
Already Exists
[p(x=1, y=2, z=0), p(x=2, y=1, z=None)]
您的示例可以在不定义您自己的 hash
函数的情况下工作,但这是一个很好的做法,因为 a == b
意味着 hash(a) == hash(b)
。在 __eq__
方法的条件下,它也可以在没有 isinstance(other, self.__class__)
的情况下工作,但这可以防止 AttributeError
在比较不同类型的对象时发生这种情况,如果你的列表 co_ord_list
也包含对象一些其他类型。