max
max

Reputation: 52323

Find all items with maximum value produced by an iterator

I want to get all the maximum values from an iterator:

def max_val(iterator, key=None):
  # ???
it = (i for i in range(4))
assert max_val(it, key=lambda i: i%2) == [1, 3]

Note: this question is similar to what was asked before for a list.

There are 2 differences with the previous question:

1) I want this to work for an iterator, so I can't use the 2-pass approach that was both the fastest and the simplest solution to the list question.

2) I want to get the maximum values rather than indices. It might sound weird, but this is useful if I specify a key argument as in the above example (or if the objects have ordering based only on part of their internal state).

One solution is a slightly modified @martineau answer to the list question (it would need to store the values instead of indices), but I was wondering if there's a faster approach.

Upvotes: 0

Views: 2404

Answers (1)

TemporalWolf
TemporalWolf

Reputation: 7952

def max_val(iterator, key=None):
    try:
        ret = [iterator.next()]
    except StopIteration:
        return []
    for val in iterator:
        if key(val) < key(ret[0]):
            continue
        elif key(val) == key(ret[0]):
            ret.append(val)
        else:
            ret = [val]
    return ret

One pass, passes your assertion.

It just keeps the best set it's found until it finds one better, then starts over.

Upvotes: 2

Related Questions