Estou usando Python max
e min
funções em listas para um algoritmo minimax e preciso do índice do valor retornado por max()
or min()
. Em outras palavras, eu preciso saber qual jogada produziu o valor máximo (no turn do primeiro jogador) ou mínimo (segundo jogador).
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)
Eu preciso ser capaz de retornar o índice real do valor mínimo ou máximo, não apenas o valor.
divmod
existe para evitar ter que dizer[i / 3, i % 3]
muito.Respostas:
fonte
tmp = min(values); return values.index(tmp)
Diga que você tem uma lista
values = [3,6,1,5]
e precisa do índice do menor elemento, ou sejaindex_min = 2
, neste caso.Evite a solução
itemgetter()
apresentada nas outras respostas e useporque não exige
import operator
nem deve ser usadoenumerate
, e é sempre mais rápido (referência abaixo) do que uma solução usandoitemgetter()
.Se você estiver lidando com matrizes numpy ou puder pagar
numpy
como uma dependência, considere também usarIsso será mais rápido que a primeira solução, mesmo se você aplicá-la a uma lista Python pura se:
numpy
matrizcomo esta referência indica:
Executei o benchmark na minha máquina com python 2.7 para as duas soluções acima (azul: python puro, primeira solução) (solução vermelha e numpy) e para a solução padrão baseada em
itemgetter()
(solução preta de referência). A mesma referência do python 3.5 mostrou que os métodos comparam exatamente o mesmo do caso do python 2.7 apresentado acimafonte
xrange()
agora está obsoleto, você pode usarrange()
import numpy as np; x = [2.3, -1.4]; np.argmin(x)
. Você verá que tambémargmin
funciona em carros alegóricosVocê pode encontrar o índice e o valor mínimo / máximo ao mesmo tempo se enumerar os itens da lista, mas execute o mínimo / máximo nos valores originais da lista. Igual a:
Dessa forma, a lista será percorrida apenas uma vez por min (ou max).
fonte
key=lambda p: p[1]
Se você deseja encontrar o índice max dentro de uma lista de números (o que parece ser o seu caso), sugiro que você use numpy:
fonte
Possivelmente, uma solução mais simples seria transformar a matriz de valores em uma matriz de valores, pares de índices e tirar o máximo / min disso. Isso daria o maior / menor índice com max / min (ou seja, os pares são comparados comparando primeiro o primeiro elemento e, em seguida, comparando o segundo elemento se os primeiros forem iguais). Observe que não é realmente necessário criar a matriz, porque min / max permitem geradores como entrada.
fonte
Dará a você o primeiro índice do mínimo.
fonte
Eu acho que a melhor coisa a fazer é converter a lista em um
numpy array
e usar esta função:fonte
Eu também estava interessado nisso e comparei algumas das soluções sugeridas usando o perfplot (um projeto de estimação para mim).
Acontece que o argmin desse numpy ,
é o método mais rápido para listas grandes o suficiente, mesmo com a conversão implícita da entrada
list
em anumpy.array
.Código para gerar o gráfico:
fonte
Use uma matriz numpy e a função argmax ()
fonte
Depois de obter os valores máximos, tente o seguinte:
Muito mais simples do que muitas opções.
fonte
Acho que a resposta acima resolve o seu problema, mas pensei em compartilhar um método que fornece o mínimo e todos os índices em que o mínimo aparece.
Isso passa na lista duas vezes, mas ainda é bastante rápido. No entanto, é um pouco mais lento do que encontrar o índice do primeiro encontro do mínimo. Portanto, se você precisar de apenas um dos mínimos, use a solução de Matt Anderson ; se precisar de todos, use isso.
fonte
Use a função do módulo numpy numpy.where
Para índice de valor mínimo:
Para índice de valor máximo:
De fato, essa função é muito mais poderosa. Você pode representar todos os tipos de operações booleanas para índice de valor entre 3 e 60:
fonte
argmin()
invés do que fez aqui.Isso é simplesmente possível usando o built-in
enumerate()
andmax()
function e okey
argumento opcional damax()
função e uma simples expressão lambda:Nos documentos para
max()
ele diz que okey
argumento espera uma função como nalist.sort()
função. Consulte também o Guia de classificação .Funciona da mesma maneira para
min()
. Entre, ele retorna o primeiro valor máximo / mínimo.fonte
Digamos que você tenha uma lista como:
Os dois métodos a seguir são maneiras bastante compactas de obter uma tupla com o elemento mínimo e seu índice. Ambos têm uma abordagem semelhante tempo ao processo. Eu gosto mais do método zip, mas esse é o meu gosto.
método zip
enumerar método
fonte
Desde que você saiba como usar o lambda e o argumento "key", uma solução simples é:
fonte
n
pode ser visivelmente mais lento.Simples assim :
fonte
Por que se preocupar em adicionar índices primeiro e depois revertê-los? A função Enumerate () é apenas um caso especial de uso da função zip (). Vamos usá-lo de maneira apropriada:
fonte
Apenas uma pequena adição ao que já foi dito.
values.index(min(values))
parece retornar o menor índice de min. A seguir, obtém o maior índice:A última linha pode ser deixada de fora se o efeito colateral da reversão no local não importar.
Para percorrer todas as ocorrências
Por uma questão de brevidade. Provavelmente, é uma idéia melhor armazenar em cache
min(values), values.count(min)
fora do loop.fonte
reversed(…)
em vez de….reverse()
provavelmente é preferível, pois não muda e retorna um gerador de qualquer maneira. E todas as ocorrências também poderia serminv = min(values); indices = [i for i, v in enumerate(values) if v == minv]
Uma maneira simples de encontrar os índices com valor mínimo em uma lista, se você não deseja importar módulos adicionais:
Em seguida, escolha, por exemplo, o primeiro:
fonte
Não tem representante alto o suficiente para comentar a resposta existente.
Mas para https://stackoverflow.com/a/11825864/3920439 answer
Isso funciona para números inteiros, mas não para matrizes flutuantes (pelo menos no python 3.6).
TypeError: list indices must be integers or slices, not float
fonte
https://docs.python.org/3/library/functions.html#max
Se vários itens forem máximos, a função retornará o primeiro encontrado. Isso é consistente com outras ferramentas de preservação da estabilidade de classificação, como
sorted(iterable, key=keyfunc, reverse=True)[0]
Para obter mais do que apenas o primeiro, use o método de classificação.
fonte
Que tal isso:
Ele cria um dicionário a partir dos itens em
a
como chaves e seus índices como valores; assim,dict(zip(a,range(len(a))))[max(a)]
retorna o valor que corresponde à chavemax(a)
que é o índice do máximo em a. Como sou iniciante em python, não conheço a complexidade computacional dessa solução.fonte