Steven D'Aprano <steve+comp.lang.python <at> pearwood.info> writes:
For example:
a=[-15,-30,-10,1,3,5]
I want to find a negative and a positive minimum.
example: negative
print(min(a)) = -30
positive
print(min(a)) = 1
Thank you for providing examples, but they don't really cover all the
possibilities. For example, if you had:
a = [-1, -2, -3, 100, 200, 300]
I can see that you consider -3 to be the "negative minimum". Do you
consider the "positive minimum" to be 100, or 1?
If you expect it to be 100, then the solution is:
min([item for item in a if item > 0])
If you expect it to be 1, then the solution is:
min([abs(item) for item in a])
which could also be written as:
min(map(abs, a))
A third alternative is in Python 3.3:
min(a, key=abs)
which will return -1.
thinking again about the question, then the min() solutions suggested so far
certainly do the job and they are easy to understand.
However, if you need to run the function repeatedly on larger lists, using min()
is suboptimal because its performance is an O(n) one.
It's faster, though less intuitive, to sort your list first, then use bisect on
it to find the zero position in it. Two manipulations running at O(log(n)).
compare these two functions:
def with_min(x):
return (min(n for n in a if n<0), min(n for n in a if n>=0))
def with_bisect(x):
b=sorted(x)
return (b[0] if b[0]<0 else None, b[bisect.bisect_left(b,0)])
then either time them for small lists or try:
a=range(-10000000,10000000)
with_min(a)
with_bisect(a)
of course, the disadvantage is that you create a huge sorted list in memory and
that it's less readable.
Best,
Wolfgang