I am not .
I’m not sure why I’m bothering to reply, I can’t tell if this is some kind of trolling or if you’re just really confused or something because you contradicted yourself multiple times already.
First you said that I had suggested adding
all(map(operator.eq, iterable[1:], iterable[:-1]))
to the Python code somewhere as an implementation of all_equal
. I did not suggest this.
Then later, you denied doing so.
Seriously? What is going on here?
First you said that I had suggested adding
all(map(operator.eq, iterable[1:], iterable[:-1]))
to the Python code somewhere as an implementation of
all_equal
.
Not true. I didn’t.
The current suggestions to implement
all_equal
are either slow, or they use some form of prematurely optimized “hack” resulting in unreadable code.
The current recipe is:
def all_equal(iterable, key=None):
"Returns True if all the elements are equal to each other."
return len(take(2, groupby(iterable, key))) <= 1
I don’t think that’s unreadable, and I don’t believe it’s slow. Of course there may be real code where a proper benchmark would find a strictly superior alternative, but I believe we are at the point where a microbenchmark isn’t particularly relevant.
If there’s a nice primitive that would make this code more readable, equally performant, and enable other common patterns, that sounds like a great candidate for a third-party library to prove out.
I don’t think that’s unreadable
Can you explain it using 1 sentence?
In fairness, the other recipe which I have seen is far worse.
next(g, True) and not next(g, False)
Try explaining that in a single sentence.
At least if you know what groupby
does, then the code you posted above is fairly obvious. However you have to know what groupby
does as a prerequisite. Since groupby
isn’t part of the standard library, this is some non-trivial amount of work you have to do to figure it out.
The main issue I take with it is the operations of checking for equality has nothing to do with grouping. It just so happens to be that if you group objects together you can use the output of this to prove by contradiction that all the elements are not equal.
Groupby must be performing an __eq__
check in order for it to work. So why not just do the __eq__
check?
I hope it doesn’t appear that I am being pedantic here. We like Python for its simplicity and “one obvious way of doing things”. This itertools recipe (the one I posted) is anything but the most obvious solution.
I agree the above alternative is better.
Since
groupby
isn’t part of the standard library
It is.
checking for equality has nothing to do with grouping
The grouping is done by checking for equality.
And quoting Raymond about all_equal
(or its old recipe version, not sure):
it gets to the heart of what
groupby
is all about which is lazily chunking groups of equal values
It just so happens to be that if you group objects together you can use the output of this to prove by contradiction that all the elements are not equal.
Which is perfectly fine and normal. Do you also dislike all
’s equivalent code
def all(iterable):
for element in iterable:
if not element:
return False
return True
because it’s supposed to check whether all elements are true, but instead checks whether they’re "not* true and doesn’t even check all elements, instead using the first not true element to “prove by contradiction that all the elements are not true”?
I needed this today but I knew my input is going to be strings (which are hashable) so I just did return len(set(myiterable)) == 1