-
Notifications
You must be signed in to change notification settings - Fork 311
all_equal() improvement #896
Copy link
Copy link
Closed
Description
The all_equal() recipe in the main itertools docs was chosen because it is a one liner, it is reasonably clear, and it nicely shows off how various tools can be chained together in a functional style.
For the production version in more-itertools, we can do better (faster startup overhead and fewer dependencies):
def all_equal(iterable, key=None):
"Returns True if all the elements are equal to each other."
# all_equal('4٤௪౪໔', key=int) → True
iterator = groupby(iterable, key=key)
try:
next(iterator)
next(iterator)
except StopIteration:
return True
return FalseHere are some timings that demonstrate reduced overhead for each of the cases (zero groups, one group, two or more groups):
% python3.13 -m timeit -s 'from itertools import islice, groupby' -s 'key=None' -s 'iterable=""' 'len(list(islice(groupby(iterable, key), 2))) <= 1'
1000000 loops, best of 5: 233 nsec per loop
% python3.13 -m timeit -s 'from itertools import islice, groupby' -s 'key=None' -s 'iterable="a"' 'len(list(islice(groupby(iterable, key), 2))) <= 1'
1000000 loops, best of 5: 256 nsec per loop
% python3.13 -m timeit -s 'from itertools import islice, groupby' -s 'key=None' -s 'iterable="ab"' 'len(list(islice(groupby(iterable, key), 2))) <= 1'
1000000 loops, best of 5: 289 nsec per loop
% python3.13 -m timeit -s 'from itertools import islice, groupby' -s 'key=None' -s 'iterable=""' 'it=groupby(iterable)' 'try:' ' next(it)' ' next(it)' 'except StopIteration:' ' True' 'else:' ' False'
2000000 loops, best of 5: 150 nsec per loop
% python3.13 -m timeit -s 'from itertools import islice, groupby' -s 'key=None' -s 'iterable="a"' 'it=groupby(iterable)' 'try:' ' next(it)' ' next(it)' 'except StopIteration:' ' True' 'else:' ' False'
2000000 loops, best of 5: 198 nsec per loop
% python3.13 -m timeit -s 'from itertools import islice, groupby' -s 'key=None' -s 'iterable="ab"' 'it=groupby(iterable)' 'try:' ' next(it)' ' next(it)' 'except StopIteration:' ' True' 'else:' ' False'
2000000 loops, best of 5: 174 nsec per loop
Downstream code such as iequals() will benefit most because it uses all_equal() in a loop.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels