Estoy usando Python max
y min
funciones en 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.
divmod
existe para evitar tener que decir[i / 3, i % 3]
mucho.Respuestas:
fuente
tmp = min(values); return values.index(tmp)
Digamos que tiene una lista
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
itemgetter()
presentada en las otras respuestas, y use en su lugarporque no requiere
import operator
ni usarenumerate
, y siempre es más rápido (punto de referencia a continuación) que una solución que usaitemgetter()
.Si está lidiando con matrices numpy o puede pagar
numpy
como una dependencia, considere también usarEsto será más rápido que la primera solución, incluso si lo aplica a una lista pura de Python si:
numpy
matrizcomo señala este punto de referencia:
He ejecutado el punto de referencia en mi máquina con python 2.7 para las dos soluciones anteriores (azul: pitón 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 lo mismo del caso de Python 2.7 presentado anteriormentefuente
xrange()
ahora está en desuso, puedes usarlorange()
import numpy as np; x = [2.3, -1.4]; np.argmin(x)
. Verás que tambiénargmin
funciona en carrozasPuede encontrar el índice y el valor mínimo / máximo al mismo tiempo si enumera los elementos de la lista, pero realiza un mínimo / máximo en los valores originales de la lista. Al igual que:
De esta forma, la lista solo se recorrerá una vez durante min (o max).
fuente
key=lambda p: p[1]
Si desea encontrar el índice de max dentro de una lista de números (que parece ser su caso), le sugiero que use numpy:
fuente
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 más grande / más pequeño 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 la matriz, ya que min / max permiten generadores como entrada.
fuente
Te dará el primer índice de mínimo.
fuente
Creo que lo mejor es convertir la lista a ay
numpy array
usar esta función:fuente
También estaba interesado en esto y comparé algunas de las soluciones sugeridas usando perfplot (un proyecto mío mío).
Resulta que el argmin de ese numpy ,
es el método más rápido para listas lo suficientemente grandes, incluso con la conversión implícita de la entrada
list
a anumpy.array
.Código para generar la trama:
fuente
Use una matriz numpy y la función argmax ()
fuente
Después de obtener los valores máximos, intente esto:
Mucho más simple que muchas opciones.
fuente
Creo que la respuesta anterior resuelve su problema, pero pensé en compartir un método que le dé el mínimo y todos los índices en los que aparece el mínimo.
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 necesita solo uno de los mínimos, use la solución de Matt Anderson , si los necesita a todos, use esto.
fuente
Use la función numpy del módulo numpy.where
Para índice de valor mínimo:
Para el índice de valor máximo:
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:
fuente
argmin()
lugar de lo que hizo aquí.Esto es simplemente posible utilizando el incorporado
enumerate()
y lamax()
función y elkey
argumento opcional de lamax()
función y una expresión lambda simple:En los documentos
max()
, dice que elkey
argumento espera una función como en lalist.sort()
función. Consulte también la Clasificación de cómo hacerlo .Funciona igual para
min()
. Por cierto, devuelve el primer valor máximo / mínimo.fuente
Digamos que tiene una lista como:
Los siguientes dos métodos son formas bastante compactas de obtener una tupla con el elemento mínimo y su índice. Ambos tardan un tiempo similar en procesarse. Mejor me gusta el método zip, pero ese es mi gusto.
método zip
método de enumeración
fuente
Mientras sepa cómo usar lambda y el argumento "clave", una solución simple es:
fuente
n
puede ser notablemente más lento.Simple como eso :
fuente
¿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:
fuente
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:La última línea se puede omitir si el efecto secundario de la inversión en su lugar no importa.
Para iterar a través de todas las ocurrencias
Por el bien de la brevedad. Probablemente sea una mejor idea almacenar en caché
min(values), values.count(min)
fuera del bucle.fuente
reversed(…)
en lugar de….reverse()
es probable que sea preferible ya que no muta y devuelve un generador de todos modos. Y todos los sucesos también podrían serminv = min(values); indices = [i for i, v in enumerate(values) if v == minv]
Una forma sencilla de encontrar los índices con un valor mínimo en una lista si no desea importar módulos adicionales:
Luego elija, por ejemplo, el primero:
fuente
No tenga un representante lo suficientemente alto como para comentar sobre la respuesta existente.
Pero para https://stackoverflow.com/a/11825864/3920439 responda
Esto funciona para enteros, pero no funciona para una matriz de flotadores (al menos en Python 3.6).
TypeError: list indices must be integers or slices, not float
fuente
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, como
sorted(iterable, key=keyfunc, reverse=True)[0]
Para obtener más que solo el primero, utilice el método de clasificación.
fuente
¿Qué hay de esto?
Crea un diccionario a partir de los elementos en
a
como claves y sus índices como valores, por lo tanto,dict(zip(a,range(len(a))))[max(a)]
devuelve el valor que corresponde a la clave,max(a)
que es el índice del máximo en a. Soy un principiante en Python, así que no sé sobre la complejidad computacional de esta solución.fuente