Search a sequence for its minimum and stop as soon as the lowest possible value is found

Antonio Caminero Garcia tonycamgar at gmail.com
Sun Jan 8 19:45:29 EST 2017


On Friday, January 6, 2017 at 6:04:33 AM UTC-8, Peter Otten wrote:
> Example: you are looking for the minimum absolute value in a series of 
> integers. As soon as you encounter the first 0 it's unnecessary extra work 
> to check the remaining values, but the builtin min() will continue.
>> The solution is a minimum function that allows the user to specify a stop 
> value:
>> >>> from itertools import count, chain
> >>> stopmin(chain(reversed(range(10)), count()), key=abs, stop=0)
> 0
>> How would you implement stopmin()?
>> Currently I raise an exception in the key function:
>> class Stop(Exception):
> pass
>> def stopmin(items, key, stop):
> """
> >>> def g():
> ... for i in reversed(range(10)):
> ... print(10*i)
> ... yield str(i)
> >>> stopmin(g(), key=int, stop=5)
> 90
> 80
> 70
> 60
> 50
> '5'
> """
> def key2(value):
> result = key(value)
> if result <= stop:
> raise Stop(value)
> return result
> try:
> return min(items, key=key2)
> except Stop as stop:
> return stop.args[0]

This is the simplest version I could come up with. I also like the classic 100% imperative, but it seems that is not trendy between the solutions given :D.
you can test it here https://repl.it/FD5A/0
source code:
from itertools import accumulate
# stopmin calculates the greatest lower bound (infimum). 
# https://upload.wikimedia.org/wikipedia/commons/0/0a/Infimum_illustration.svg 
def takeuntil(pred, seq):
 for item in seq:
 yield item
 if not pred(item):
 break
def stopmin(seq, stop=0):
 drop_ltstop = (item for item in seq if item >= stop)
 min_gen = (min_ for min_ in accumulate(drop_ltstop, func=min))
 return list(takeuntil(lambda x: x!= stop, min_gen))[-1]
seq = [1, 4, 7, -8, 0, 7, -8, 9] # 0 just until zero is generated
seq = [1, 4, 7, -8, 7, -8, 9] # 1 the entire sequence is generated
print(stopmin(seq, stop=0))


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /