Implement the argmin function from math, in a form that makes use of generator expressions in 2.4.
1 2 3 4 5 6 7 8 9 | def argmin(sequence, fn=None):
"""Two usage patterns:
argmin([s0, s1, ...], fn)
argmin([(fn(s0), s0), (fn(s1, s1), ...])
Both return the si with lowest fn(si)"""
if fn is None:
return min(sequence)[1]
else:
return min((fn(e), e) for e in sequence)[1]
|
Often you want to find the element of a set that is "best" in some way. In math, this is usually notated with argmin (or argmax):
best = argmine in S f(e)
where f is a function that gives a score, and low score is best. Python syntax doesn't allow subscripts like this, but we can come up with two protocols that are not too ugly. Examples:
If we have sequence = ['one', 'to', 'three'], then
argmin(sequence, len) ==> 'to' ## because 'to' has smallest len.
argmin((len(x), x) for x in sequence) ==> 'to' ## alternate protocol
Note that with generator expressions this is efficient (doesn't build up a large intermediate list) and not too hard to read.
essentially min with a key argument. argmin is essentially min with a key argument like what list.sort and sorted have. Note that min and max now take such 'key' arguments in the current Python cvs:
Of course, most people can't use the current CVS version of Python, so here's a substitute:
Now you should be able to use key arguments to min and max just like in CVS:
As far as I understand, in math, arg functions return the _argument_ of our actual functions, which means that the point(s) at which the values of our function is minimal/maximal.
So for example if our function is:
then the minimum value of the function is 3, and the point where our function takes its minimum value is x=0.
In Python, this translates to returning the index of the minimum element in the sequence, not the actual minimum element. In this sense, argmin means something like this: