Obtención del índice del artículo máximo o mínimo devuelto utilizando max () / min () en una lista

Estoy usando las funciones max y min Python en las listas para un algoritmo minimax, y necesito el índice del valor devuelto por max() o min() . En otras palabras, necesito saber qué movimiento produjo el valor máximo (en el turno del primer jugador) o mínimo (segundo jugador).

 for i in range(9): newBoard = currentBoard.newBoardWithMove([i / 3, i % 3], player) if newBoard: temp = minMax(newBoard, depth + 1, not isMinLevel) values.append(temp) if isMinLevel: return min(values) else: return max(values) 

Necesito poder devolver el índice real del valor mínimo o máximo, no solo el valor.

 si esMinLevel:
     devuelve values.index (min (valores))
 más:
     devuelve values.index (max (valores))

Digamos que tiene una lista de values = [3,6,1,5] , y necesita el índice del elemento más pequeño, es decir, index_min = 2 en este caso.

Evite la solución con itemgetter() presentada en las otras respuestas, y use en su lugar

 index_min = min(xrange(len(values)), key=values.__getitem__) 

porque no requiere import operator ni utilizar enumerate , y siempre es más rápido (punto de referencia a continuación) que una solución que usa itemgetter() .

Si está tratando con matrices numpy o puede permitirse el numpy como una dependencia, considere también usar

 import numpy as np index_min = np.argmin(values) 

Esto será más rápido que la primera solución, incluso si lo aplica a una lista de Python pura si:

  • es más grande que algunos elementos (aproximadamente 2 ** 4 elementos en mi máquina)
  • Puede pagar la copia de memoria de una lista pura a una matriz numpy

Como señala este punto de referencia: introduzca la descripción de la imagen aquí

He ejecutado el benchmark en mi máquina con python 2.7 para las dos soluciones anteriores (azul: python puro, primera solución) (rojo, solución numpy) y para la solución estándar basada en itemgetter() (negro, solución de referencia). El mismo punto de referencia con Python 3.5 mostró que los métodos comparan exactamente el mismo caso de Python 2.7 presentado anteriormente.

Puede encontrar el índice y el valor mínimo / máximo al mismo tiempo si enumera los elementos en la lista, pero realiza el mínimo / máximo en los valores originales de la lista. Al igual que:

 import operator min_index, min_value = min(enumerate(values), key=operator.itemgetter(1)) max_index, max_value = max(enumerate(values), key=operator.itemgetter(1)) 

De esta manera, la lista solo se recorrerá una vez por mín (o máx).

Si desea encontrar el índice de max dentro de una lista de números (lo que parece ser su caso), le sugiero que use numpy:

 import numpy as np ind = np.argmax(mylist) 

Posiblemente una solución más simple sería convertir la matriz de valores en una matriz de valores, pares de índices, y tomar el máximo / mínimo de eso. Esto daría el índice mayor / menor que tiene el máximo / mínimo (es decir, los pares se comparan primero comparando el primer elemento, y luego comparando el segundo elemento si los primeros son iguales). Tenga en cuenta que no es necesario crear realmente la matriz, ya que los generadores permiten el máximo / máximo como entrada.

 values = [3,4,5] (m,i) = max((v,i) for i,v in enumerate(values)) print (m,i) #(5, 2) 
 list=[1.1412, 4.3453, 5.8709, 0.1314] list.index(min(list)) 

Te daremos el primer índice de mínimos.

También me interesó esto y comparé algunas de las soluciones sugeridas utilizando perfplot (uno de mis proyectos favoritos).

Resulta que el argmin de ese numpy ,

 numpy.argmin(x) 

es el método más rápido para listas lo suficientemente grandes, incluso con la conversión implícita de la list entrada a un numpy.array .

introduzca la descripción de la imagen aquí


Código para generar la ttwig:

 import numpy import operator import perfplot def min_enumerate(a): return min(enumerate(a), key=lambda x: x[1])[0] def min_enumerate_itemgetter(a): min_index, min_value = min(enumerate(a), key=operator.itemgetter(1)) return min_index def getitem(a): return min(range(len(a)), key=a.__getitem__) def np_argmin(a): return numpy.argmin(a) perfplot.show( setup=lambda n: numpy.random.rand(n).tolist(), kernels=[ min_enumerate, min_enumerate_itemgetter, getitem, np_argmin, ], n_range=[2**k for k in range(15)], logx=True, logy=True, ) 

Use una matriz numpy y la función argmax ()

  a=np.array([1,2,3]) b=np.argmax(a) print(b) #2 

Usar la función numpy del módulo numpy.

 import numpy as n x = n.array((3,3,4,7,4,56,65,1)) 

Para índice de valor mínimo:

 idx = n.where(x==x.min())[0] 

Para índice de máximo valor:

 idx = n.where(x==x.max())[0] 

De hecho, esta función es mucho más poderosa. Puede plantear todo tipo de operaciones booleanas Para un índice de valor entre 3 y 60:

 idx = n.where((x>3)&(x<60))[0] idx array([2, 3, 4, 5]) x[idx] array([ 4, 7, 4, 56]) 

Después de obtener los valores máximos, intente esto:

 max_val = max(list) index_max = list.index(max_val) 

Mucho más simple que muchas opciones.

Creo que la respuesta anterior resuelve tu problema, pero pensé que compartiría un método que te dé el mínimo y todos los índices en los que aparece el mínimo.

 minval = min(mylist) ind = [i for i, v in enumerate(mylist) if v == minval] 

Esto pasa la lista dos veces, pero sigue siendo bastante rápido. Sin embargo, es un poco más lento que encontrar el índice del primer encuentro del mínimo. Entonces, si solo necesita uno de los mínimos, use la solución de Matt Anderson , si los necesita todos, use esto.

Esto es simplemente posible usando las funciones enumerate() y max() integradas y el argumento key opcional de la función max() y una expresión lambda simple:

 theList = [1, 5, 10] maxIndex, maxValue = max(enumerate(theList), key=lambda v: v[1]) # => (2, 10) 

En los documentos para max() dice que el argumento key espera una función como en la función list.sort() . También vea el Cómo ordenar .

Funciona igual para min() . Por cierto, devuelve el primer valor máximo / mínimo.

Mientras sepa cómo usar lambda y el argumento “clave”, una solución simple es:

 max_index = max( range( len(my_list) ), key = lambda index : my_list[ index ] ) 

Digamos que tienes una lista como:

 a = [9,8,7] 

Los dos métodos siguientes son formas bastante compactas de obtener una tupla con el elemento mínimo y su índice. Ambos toman un tiempo similar para procesar. Me gusta más el método zip, pero ese es mi gusto.

método zip

 element, index = min(list(zip(a, range(len(a))))) min(list(zip(a, range(len(a))))) (7, 2) timeit min(list(zip(a, range(len(a))))) 1.36 µs ± 107 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) 

método de enumeración

 index, element = min(list(enumerate(a)), key=lambda x:x[1]) min(list(enumerate(a)), key=lambda x:x[1]) (2, 7) timeit min(list(enumerate(a)), key=lambda x:x[1]) 1.45 µs ± 78.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) 

¿Por qué molestarse en agregar índices primero y luego revertirlos? La función Enumerate () es solo un caso especial de uso de la función zip (). Vamos a usarlo de manera apropiada:

 my_indexed_list = zip(my_list, range(len(my_list))) min_value, min_index = min(my_indexed_list) max_value, max_index = max(my_indexed_list) 

Creo que lo mejor es convertir la lista en una numpy array y usar esta función:

 a = np.array(list) idx = np.argmax(a) 

Solo una pequeña adición a lo que ya se ha dicho. values.index(min(values)) parece devolver el índice más pequeño de min. Lo siguiente obtiene el índice más grande:

  values.reverse() (values.index(min(values)) + len(values) - 1) % len(values) values.reverse() 

La última línea se puede omitir si el efecto secundario de revertir en el lugar no importa.

Recorrer todas las ocurrencias.

  indices = [] i = -1 for _ in range(values.count(min(values))): i = values[i + 1:].index(min(values)) + i + 1 indices.append(i) 

Por el bien de la brevedad. Probablemente sea una mejor idea almacenar en caché min(values), values.count(min) fuera del bucle.

Una forma sencilla de encontrar los índices con un valor mínimo en una lista si no desea importar módulos adicionales:

 min_value = min(values) indexes_with_min_value = [i for i in range(0,len(values)) if values[i] == min_value] 

Luego elige por ejemplo el primero:

 choosen = indexes_with_min_value[0] 

Simple como eso :

 stuff = [2, 4, 8, 15, 11] index = stuff.index(max(stuff)) 

No tengo suficiente reputación para comentar sobre la respuesta existente.

Pero para https://stackoverflow.com/a/11825864/3920439 responda

Esto funciona para los enteros, pero no funciona para la matriz de flotantes (al menos en Python 3.6) TypeError: list indices must be integers or slices, not float

https://docs.python.org/3/library/functions.html#max

Si varios elementos son máximos, la función devuelve el primero encontrado. Esto es consistente con otras herramientas de preservación de la estabilidad de clasificación, tales como sorted(iterable, key=keyfunc, reverse=True)[0]

Para obtener más que solo el primer uso del método de clasificación.

 import operator x = [2, 5, 7, 4, 8, 2, 6, 1, 7, 1, 8, 3, 4, 9, 3, 6, 5, 0, 9, 0] min = False max = True min_val_index = sorted( list(zip(x, range(len(x)))), key = operator.itemgetter(0), reverse = min ) max_val_index = sorted( list(zip(x, range(len(x)))), key = operator.itemgetter(0), reverse = max ) min_val_index[0] >(0, 17) max_val_index[0] >(9, 13) import ittertools max_val = max_val_index[0][0] maxes = [n for n in itertools.takewhile(lambda x: x[0] == max_val, max_val_index)]