It's expected that python single iterating would be slower than two times C iterating. Nevertheless one time C iterating will be probably faster than a separate min + index.

>> I think one would want argmin() and argmax() to work with general iterables
How is it supposed to work with set or dict or other iterables without clear order?

My last case was to find the min index of the array part. index_min could accept the starting element index, as index does.

a = [1, 4, 1, 2, 3]
print(a.index_min())      # 0
print(a.index_min(1))    # 2



On Sun, 30 Aug 2020 at 11:52, Barry Scott <barry@barrys-emacs.org> wrote:


On 30 Aug 2020, at 09:03, Jeff Allen <ja.py@farowl.co.uk> wrote:

On 29/08/2020 14:17, Barry Scott wrote:
On 29 Aug 2020, at 13:42, Filipp Bakanov <filipp@bakanov.su> wrote:

I'd like to propose adding argmax and argmin functions to the python list. These functions return the index of a maximum / minimum element of the list. Eg:

a = [1, 4, 2, 3]
print(a.argmax())  # 1
print(a.argmin())  # 0

It's a very popular request (based on stackoverflow https://stackoverflow.com/questions/16945518/finding-the-index-of-the-value-which-is-the-min-or-max-in-python ), and currently there is no elegant way to find it.

What do you think?

Just do this:

>>> a=[1,4,2,3]
>>> min(a)
1
>>> a.index(min(a))
0
>>> a.index(max(a))
1

Barry

This has the drawback of passing twice over the list. The following doesn't, but the complexity somewhat makes Filipp's point:

>>> min((e, i) for i, e in enumerate(a))[1]
0

That is 4x slower then my code for 1,000,000 items.

--------------- a.py --------------
import sys
import time
import random

alg = sys.argv[1]
size = int(sys.argv[2])

x = [random.randint(0, 1_000_000) for _ in range(size)]

start = time.time()

if alg == 'barry':

    m = x.index(min(x))

elif alg == 'jeff':

    m = min((e, i) for i, e in enumerate(x))[1]

end = time.time()

print( alg, end-start, (end-start)/size )
-------------------------

Here is the output I got on my laptop.

barry 0.022754907608032227 2.2754907608032226e-08
barry 0.03325295448303223 3.325295448303223e-08
barry 0.034243106842041016 3.4243106842041016e-08
barry 0.02784109115600586 2.784109115600586e-08
jeff 0.13722586631774902 1.3722586631774904e-07
jeff 0.1359708309173584 1.359708309173584e-07
jeff 0.13658690452575684 1.3658690452575684e-07

I think one would want argmin() and argmax() to work with general iterables, so I wonder if the stdlib would not be a better home than list itself. I half expected it to be an itertools recipe. The advantage of a recipe is that variations such as needing the last occurrence of the minimum are easily accommodated.


Surely its index_min() and index_max() not argmin() and argmax().

Barry

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/VMSSYHAOST7K3WNHO3JOQENI6G5CXZZ5/
Code of Conduct: http://python.org/psf/codeofconduct/