Python中集合对命名元组的in操作原理探究
集合
in操作对命名元组的工作逻辑 集合的成员判断(in操作)不直接依赖对象ID,而是基于两个核心步骤:
- 计算待检查元素的哈希值,定位到集合中对应的哈希桶
- 在该哈希桶内,通过相等性判断(
==)逐一对比元素
- 在该哈希桶内,通过相等性判断(
而collections.namedtuple创建的类是元组的子类,完全继承了元组的哈希与相等性实现规则:
- 命名元组的哈希值由其所有字段的哈希值共同计算得出
- 命名元组的相等性判断会逐个对比所有字段的取值是否完全一致
回到你的代码例子:
- 两次调用
pos(1,1)生成的实例虽然id不同,但它们的所有字段值完全相同,因此两者的哈希值一致,且pos(1,1) == pos(1,1)返回True - 当执行
pos(1,1) in x时,集合先通过哈希值找到对应的桶,再通过相等性检查匹配到已存在的元素,因此返回True - 而
pos(1,2)与集合内元素的字段值不同,哈希值不匹配,相等性判断也不通过,所以返回False
对比普通自定义类:普通类默认的__hash__基于对象ID,__eq__也是直接对比ID,所以即使两个实例内容一致,in集合也会返回False——但命名元组因为继承了元组的行为,才会有这种“匹配内容而非对象本身”的特性。
内容的提问来源于stack exchange,提问作者Abhishek Bhatia
相关产品推荐
相关产品推荐

