Skip to content Skip to sidebar Skip to footer

Lazy Way To Check If All Generated Elements Are Equal

Given an iterator that yields comparable values, what would be the lazy way to check if all results are equal. That is, fail as soon as possible, without consuming the whole genera

Solution 1:

How about:

first = next(gen)
if all(x==first for x in gen):
    print "They're all the same!"

(Rob Wouters described this algorithm in a comment, I just put it into Python)

As F.J spotted, this will fail on an empty iterator, and it assumes you've already got an iterator, not just an iterable. His answer addresses both points.


Solution 2:

Expression as given by @unutbu

all(y == first for first in gen for y in gen)

Test/demo:

>>> def test(*args):
...     for a in args:
...         print a,
...         yield a
... 
>>> g = test(1,1,1,1,1,1,1)
>>> print all(a == x for a in g for x in g)
1 1 1 1 1 1 1 True
>>> g = test(1,1,1,2,1,1,1)
>>> print all(a == x for a in g for x in g)
1 1 1 2 False

Failed early, as required.


Solution 3:

def all_equal(iterable):
    itr = iter(iterable)
    try:
        first = next(itr)
    except StopIteration:
        return True
    else:
        return all(item == first for item in itr)
  • Returns True for empty iterables
  • Works for any iterable, not just generators

Solution 4:

from itertools import *

if all(a == b for a, b in izip(gen, islice(gen, 1, None))):
    print "They're all the same!"

Although that wouldn't work for iterators.

gen1, gen2 = tee(gen)
next(gen1, None)
if all(a == b for a, b in izip(gen1, gen2)):
    print "They're all the same!"

Or as a "single expression":

if (lambda g, h: all(a == b for a, b in izip(g, islice(h, 1, None))))(*tee(gen)):
    print "They're all the same!"

Post a Comment for "Lazy Way To Check If All Generated Elements Are Equal"