Re: Finding the Min for positive and negative in python 3.3 list

2013-03-14 Thread 88888 Dihedral
Wolfgang Maier於 2013年3月13日星期三UTC+8下午6時43分38秒寫道:
 Steven D'Aprano steve+comp.lang.python at pearwood.info writes:
 
 
 
  
 
  On Tue, 12 Mar 2013 17:03:08 +, Norah Jones wrote:
 
  
 
   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 n0), 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(-1000,1000)
 
 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

Sorting numbers of such range M in a list of length N by radix sort 
is faster but requires more memory.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Wolfgang Maier
Steven D'Aprano steve+comp.lang.python at pearwood.info writes:

 
 On Tue, 12 Mar 2013 17:03:08 +, Norah Jones wrote:
 
  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 n0), 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(-1000,1000)
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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Oscar Benjamin
On 13 March 2013 10:43, Wolfgang Maier
wolfgang.ma...@biologie.uni-freiburg.de wrote:

 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)).

Sort cannot be O(log(n)) and it cannot be faster than a standard O(n)
minimum finding algorithm. No valid sorting algorithm can have even a
best case performance that is better than O(n). This is because it
takes O(n) just to verify that a list is sorted.


Oscar
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Wolfgang Maier
Oscar Benjamin oscar.j.benjamin at gmail.com writes:

 
 Sort cannot be O(log(n)) and it cannot be faster than a standard O(n)
 minimum finding algorithm. No valid sorting algorithm can have even a
 best case performance that is better than O(n). This is because it
 takes O(n) just to verify that a list is sorted.
 
 Oscar
 

Oops, you're right of course.
Wrote this in a hurry before and got confused a bit.
So, the two min()s take O(n) each, the sort takes O(n),
but the bisect takes O(log n),
which means that sorting and bisecting together should still be faster
than 2xmin(), although it's a bit less striking than what I wrote first.
Thanks for the correction,
Wolfgang



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Chris Angelico
On Wed, Mar 13, 2013 at 10:23 PM, Oscar Benjamin
oscar.j.benja...@gmail.com wrote:
 On 13 March 2013 10:43, Wolfgang Maier
 wolfgang.ma...@biologie.uni-freiburg.de wrote:

 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)).

 Sort cannot be O(log(n)) and it cannot be faster than a standard O(n)
 minimum finding algorithm. No valid sorting algorithm can have even a
 best case performance that is better than O(n). This is because it
 takes O(n) just to verify that a list is sorted.

Or looking at it another way: Sorting a list will require, at a bare
minimum, comparing every element against at least one other element -
if you could reduce it below that, there would be some element whose
position you cannot know. Finding the minimum requires precisely that
number of comparisons: each item against the one current minimum. :)

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Chris Angelico
On Wed, Mar 13, 2013 at 10:34 PM, Wolfgang Maier
wolfgang.ma...@biologie.uni-freiburg.de wrote:
 Oscar Benjamin oscar.j.benjamin at gmail.com writes:


 Sort cannot be O(log(n)) and it cannot be faster than a standard O(n)
 minimum finding algorithm. No valid sorting algorithm can have even a
 best case performance that is better than O(n). This is because it
 takes O(n) just to verify that a list is sorted.

 Oscar


 Oops, you're right of course.
 Wrote this in a hurry before and got confused a bit.
 So, the two min()s take O(n) each, the sort takes O(n),
 but the bisect takes O(log n),
 which means that sorting and bisecting together should still be faster
 than 2xmin(), although it's a bit less striking than what I wrote first.
 Thanks for the correction,
 Wolfgang

Your sort is usually going to be O(n log n), not O(log n).

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Peter Otten
Wolfgang Maier wrote:

 Oscar Benjamin oscar.j.benjamin at gmail.com writes:
 
 
 Sort cannot be O(log(n)) and it cannot be faster than a standard O(n)
 minimum finding algorithm. No valid sorting algorithm can have even a
 best case performance that is better than O(n). This is because it
 takes O(n) just to verify that a list is sorted.
 
 Oscar
 
 
 Oops, you're right of course.
 Wrote this in a hurry before and got confused a bit.
 So, the two min()s take O(n) each, the sort takes O(n),

O(n*log(n)) according to

http://wiki.python.org/moin/TimeComplexity

 but the bisect takes O(log n),
 which means that sorting and bisecting together should still be faster
 than 2xmin(), although it's a bit less striking than what I wrote first.

That's not how big-O math works. 2*O(n) is still O(n).

2*O(n) == O(n)

As n grows an O(log(n)) approach will eventually be faster than O(n), but 
that's asymptotical behaviour and allows for an arbitrary constant factor. 
For a given n you cannot decide if the O(n) or the O(log(n)) algorithm is 
faster unless you know these constant factors. 

Put another way: Iterating twice over the list doubles an unknown constant 
factor.



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Steven D'Aprano
On Wed, 13 Mar 2013 11:23:22 +, Oscar Benjamin wrote:

 On 13 March 2013 10:43, Wolfgang Maier
 wolfgang.ma...@biologie.uni-freiburg.de wrote:

 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)).
 
 Sort cannot be O(log(n)) and it cannot be faster than a standard O(n)
 minimum finding algorithm. No valid sorting algorithm can have even a
 best case performance that is better than O(n). This is because it takes
 O(n) just to verify that a list is sorted.

That's almost true. It applies to comparison sorts, that is, the kind of 
sort algorithm where you have to compare the elements being sorted to 
know where they go. But it doesn't necessarily apply to non-comparison 
sorts. For example, Bead sort could in principle operate in O(sqrt(n)) 
time, or even O(1), although in practice it is O(n).

Another example is Bitonic sort, which is O(log(n)**2).

In practical terms though, you are right. There is no practical, general 
purpose sorting algorithm that can beat O(n) for arbitrary lists of data.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Wolfgang Maier
Chris Angelico rosuav at gmail.com writes:


  Sort cannot be O(log(n)) and it cannot be faster than a standard O(n)
  minimum finding algorithm. No valid sorting algorithm can have even a
  best case performance that is better than O(n). This is because it
  takes O(n) just to verify that a list is sorted.
 
 Or looking at it another way: Sorting a list will require, at a bare
 minimum, comparing every element against at least one other element -
 if you could reduce it below that, there would be some element whose
 position you cannot know. Finding the minimum requires precisely that
 number of comparisons: each item against the one current minimum. :)
 
 ChrisA
 

Shame on me! You really shouldn't post things, while working on something else
that needs all your attention. You're absolutely right with what you're saying.
I was so fixed on speeding things up with the use of bisect that I wasn't really
thinking carefully about the sorting, and I was delighted when I saw that my
solution was speeding up the range() input example.
Unfortunately, it's only speedy for this example because the input is actually
sorted from the start (so sorted just checks the list - O(n)). When you use it
on shuffled input, performance is really poor as opposed to the simple min()
solution, so as pointed out by you the costs of sorting are higher than the gain
from using bisect.
What started this whole mess was my gut feeling that you should somehow be able
to exploit all the information you have, and that is that the second minimum
you're looking for cannot be negative, so is at least 0 (or 1 depending on how
you decide to treat 0). So I thought that under this restriction there should be
a faster way to find the minimum than with min(). It only fooled me into
thinking that bisect could be used for it though. Is it really impossible to
beat the min() solution then?

Thanks for your feedback,
Wolfgang

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-13 Thread Mark Lawrence

On 13/03/2013 14:12, Steven D'Aprano wrote:

On Wed, 13 Mar 2013 11:23:22 +, Oscar Benjamin wrote:


On 13 March 2013 10:43, Wolfgang Maier
wolfgang.ma...@biologie.uni-freiburg.de wrote:


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)).


Sort cannot be O(log(n)) and it cannot be faster than a standard O(n)
minimum finding algorithm. No valid sorting algorithm can have even a
best case performance that is better than O(n). This is because it takes
O(n) just to verify that a list is sorted.


That's almost true. It applies to comparison sorts, that is, the kind of
sort algorithm where you have to compare the elements being sorted to
know where they go. But it doesn't necessarily apply to non-comparison
sorts. For example, Bead sort could in principle operate in O(sqrt(n))
time, or even O(1), although in practice it is O(n).

Another example is Bitonic sort, which is O(log(n)**2).

In practical terms though, you are right. There is no practical, general
purpose sorting algorithm that can beat O(n) for arbitrary lists of data.



For the newbies hanging around there's Python's own Timsort which 
apparantly has worst case performance O(n log n), best case O(n) and 
average case O(n log n).  Please don't shoot the messenger :)




--
Cheers.

Mark Lawrence

--
http://mail.python.org/mailman/listinfo/python-list


Finding the Min for positive and negative in python 3.3 list

2013-03-12 Thread Norah Jones
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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-12 Thread Jean-Michel Pichavant

- Original Message - 

 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
 --
 http://mail.python.org/mailman/listinfo/python-list

min(a)

and

min([e for e in a if e =0]

Cheers,

JM


-- IMPORTANT NOTICE: 

The contents of this email and any attachments are confidential and may also be 
privileged. If you are not the intended recipient, please notify the sender 
immediately and do not disclose the contents to any other person, use it for 
any purpose, or store or copy the information in any medium. Thank you.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-12 Thread Wolfgang Maier
Norah Jones nh.jones01 at gmail.com 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
 
 
 

try this:
min(a)   = -30
min([n for n in a if i0])   = 1

of course, you have to figure out what you want to do with a zero value.






-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-12 Thread Devin Jeanpierre
 min(a)

This does not return a negative minimum on input [1] (because there is none).

 and

 min([e for e in a if e =0]

This does not return a positive minimum on input [0] (because there is none).

I would have said:

pos_min = min(e for e in a if e  0)
neg_min = min(e for e in a if e  0)

And then deal with the ValueError when there is no such minimum, as appropriate.

-- Devin
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-12 Thread Terry Reedy

On 3/12/2013 1:03 PM, Norah Jones wrote:

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


If this is homework, stop reading and do it yourself ;-)
Otherwise...
 min(i for i in a if i 0)
1
 max(i for i in a if i  0)
-10
 min(i for i in a if i  0)
-30

You did not specify if you would include 0 in a pos min (0 is neither 
really positive or negative).


--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-12 Thread Wolfgang Maier
Wolfgang Maier wolfgang.maier at biologie.uni-freiburg.de writes:

 
 Norah Jones nh.jones01 at gmail.com 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
  
  
  
 
 try this:
 min(a)   = -30
 min([n for n in a if n0])   = 1
 
 of course, you have to figure out what you want to do with a zero value.
 
 

the i above has to be an n, of course, sorry for that typo.

by the way, if you need both values and your list is really huge, an explicit
for loop checking each number whether it's the current negative and positive
minimum might be faster, but that would have to be tested. Also, I'm wondering
whether you could somehow exploit the fact that if your list contains 0 (or 1
depending on how you want to treat zero values) you have for sure found the
minimum for your positive numbers? 





-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Finding the Min for positive and negative in python 3.3 list

2013-03-12 Thread Steven D'Aprano
On Tue, 12 Mar 2013 17:03:08 +, Norah Jones wrote:

 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.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list