简体   繁体   English

为什么迭代器和生成器是可散列的?

[英]Why iterators and generators are hashable?

As title.如题。 I mean, you can invoke next(obj) and point to the next element.我的意思是,您可以调用next(obj)并指向下一个元素。 So the internal state of the iterable or generator will change.所以迭代器或生成器的内部 state 会发生变化。

Why they are hashable?为什么它们是可散列的?

The general rule for hashing objects is:散列对象的一般规则是:

  1. Unless __eq__ is overridden, object equality is defined by identity, and hashing matches除非__eq__被覆盖,否则 object 相等性由身份定义,并且散列匹配
  2. If __eq__ is overridden, and __hash__ is not, then hashing is blocked by default (because mutability that effects the result of an equality check would break the hash invariants);如果__eq__被覆盖,而__hash__未被覆盖,则默认情况下会阻止散列(因为影响相等性检查结果的可变性会破坏 hash 不变量); re-enabling hashing requires implementing __hash__ , which implicitly says "My equality and hash semantics are stable/consistent over time", but doesn't require that things not tied to equality or the hash code be stable.重新启用散列需要实现__hash__ ,它隐含地说“我的相等性和 hash 语义随着时间的推移是稳定/一致的”,但不要求与相等性无关的事物或 hash 代码是稳定的。

Point is, the condition for hashability isn't immutability, it's consistency with equality (and implied stability of both equality and hash).关键是,哈希性的条件不是不变性,而是与相等性的一致性(以及相等性和哈希的隐含稳定性)。 Since most iterators and all generators don't implement __eq__ (there is no meaningful way to implement it without running out the iterator and losing the information you just used to compare it), it's all based on identity, just like with any user-defined object that doesn't define equality.由于大多数迭代器和所有生成器都没有实现__eq__ (没有有意义的方法来实现它而不用完迭代器并丢失你刚刚用来比较它的信息),它都是基于身份的,就像任何用户定义的一样object 没有定义相等。

While the internal state of the generator can change, the generator as a whole can never add something to itself, and can never go back a step while iterating over it.虽然生成器的内部 state 可以更改,但生成器作为一个整体永远不能向自身添加任何东西,并且 go 在迭代它时永远不能退一步。 Therefore, a generator is a fixed immutable object, which is almost the definition of being hashable.因此,生成器是一个固定不变的 object,这几乎是可哈希的定义。

But even more deeply than that, even mutable objects can be hashable as long as they define __hash__ as an instance method, but that is rarely desireable for mutable objects.但更深层次的是,即使可变对象也可以是可散列的,只要它们将__hash__定义为实例方法,但这对于可变对象来说很少需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM