`x in List` 与 `x in Dict` 和 `x in Set` 之间的区别(其中 `x` 是极坐标数据类型)

joh*_*ger 2 python python-polars

这主要是一个关于 python 的问题:How x in [a, b, c]isvalued different from x in {a, b, c}.

我正在努力解决的上下文是这样的:

import polars as pl
s = pl.Series(["a", "b"], dtype=pl.Categorical)

s.dtype in [pl.Categorical, pl.Enum]  # True
s.dtype in {pl.Categorical, pl.Enum}  # False
s.dtype in {pl.Categorical: 1, pl.Enum: 2} # False
Run Code Online (Sandbox Code Playgroud)

我想更好地理解Python。我还想知道极地是否可以做任何事情来使第二种情况起作用,因为它目前看起来像一把步枪。

jul*_*ine 5

编辑:polar dtypes 不以多种方式遵循通常​​的 equals-contract,这是通过设计考虑的: https: //github.com/pola-rs/polars/issues/9564(感谢@jqurious),具体来说,它们违反了传递性和哈希码一致性。在极坐标中,即使不同的特定数据类型彼此不相等,特定数据类型也被视为等于更通用的数据类型。例如“ pl.List == pl.List(str)=> True pl.List(int) == pl.List(str)=> False”。


原始答案,我假设哈希码不一致就是这里发生的一切:

这是一个被破坏的平等实现。看看这个:

import polars as pl
s = pl.Series(["a", "b"], dtype=pl.Categorical)

print(s.dtype is pl.Categorical) # False 
print(s.dtype == pl.Categorical) # True
print(hash(s.dtype) == hash(pl.Categorical) ) # False
Run Code Online (Sandbox Code Playgroud)

s.dtype是一个被认为等于 的新对象pl.Categorical。但是,该__hash__函数未正确覆盖:被视为相等的两个对象必须具有相同的哈希码(或禁止使用哈希函数)。如果类不是这样的话,算法可能会依赖于此并产生奇怪的结果!如果您覆盖__eq__某个类,请阅读以下内容:https : //docs.python.org/3/reference/datamodel.html#object.__hash__

这里发生的事情是obj in list迭代列表并测试元素与 obj 的相等性,同时obj in set使用 obj 的哈希码在集合中定位对象,如果集合中不存在具有该哈希码的对象,则结论是它不存在在集合中。