python-3.x - 使用 namedtuple 的部分属性进行比较
问题描述
我有一个带有字段 (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'已经存在时,我不希望将'c'添加到列表中。
实际输出:[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)
. isinstance(other, self.__class__)
如果没有方法中的条件,它也可以工作,__eq__
但这可以防止AttributeError
在比较不同类型的对象时发生这种情况,如果您的列表co_ord_list
还包含其他类型的对象。
推荐阅读
- perl - 使用 sed/awk/perl 获取列列表
- docker - 在 docker 上运行的 Gitlab 社区 - Heathcheck
- python - 如何在 python-socketio 上发送消息
- android-studio - 如何确定 Android Studio 中方法调用(或特定行)代码的数量?
- c# - 如何从 xml 文件中读取多个属性
- java - 我们如何编辑 Java 内置类,例如 Java.util.Scanner?
- java - ActionListener 按钮什么都不做
- javascript - 使用 AJAX 和按钮提交的 Flask 上传文件不起作用
- css - 用线悬停挥动
- flutter - 如何在 Flutter Tabs 中添加圆点作为指示器?