On Wed, Dec 30, 2020 at 05:30:52PM -0800, Andres Torres wrote:
As the title suggests, I am requesting an user defined __eq__ method for the itertools.cycle class. A suggestion for how equivalency might work is that __eq__ would return True if two cyclers have the same iterable and are at the same location in their cycle and False in any other condition.
When would you use this proposed feature? Can you give an example of code that would need to check for cycle equality?
There's also a bit of a problem with the idea of "the same iterable".
Do you mean literally "the same" in the sense of identity, `is`? If so, then these two cycles will not be equal:
a = cycle([1, 2, 3]) b = cycle([1, 2, 3]) a == b # always False
even though they give the same values in the same order and are at the same point in their cycles.
But if you mean "the same" in the sense of equality you have the opposite problem, because iterator equality rightly can only check for identity. E.g. it's not practical for the interpreter to recognise that these two generators are equal, even though the human reader can:
(s for s in ('alpaca', 'buffalo', 'camel', 'dugong')) (c.lower() for c in 'DCBA'[::-1])
In general, iterators can only compare by identity, so will miss "equal but distinct" iterators:
But there's a bigger issue with the concept of cycle equality. Consider this case:
it = iter([1, 2, 3]) a = cycle(it) b = cycle(it) a == b # True by your proposal
By your definition the cycles are equal. They both have the same iterable (whether by equality or identity) and they are both in the same state. So far so good. But look at the values they produce:
>>> print(next(a), next(b)) 1 2 >>> print(next(a), next(b)) 3 2 >>> print(next(a), next(b)) 1 2 >>> print(next(a), next(b)) 3 2
So we have two equal cycle objects that nevertheless generate radically different values. Ouch.