J'utilise Python max
et les min
fonctions sur les listes pour un algorithme minimax, et j'ai besoin de l'index de la valeur retournée par max()
ou min()
. En d'autres termes, j'ai besoin de savoir quel mouvement a produit la valeur max (au tour d'un premier joueur) ou min (deuxième joueur).
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)
J'ai besoin de pouvoir renvoyer l'index réel de la valeur min ou max, pas seulement la valeur.
divmod
existe pour éviter d'avoir à en dire[i / 3, i % 3]
beaucoup.Réponses:
la source
tmp = min(values); return values.index(tmp)
Disons que vous avez une liste
values = [3,6,1,5]
et que vous avez besoin de l'index du plus petit élément, c'est-index_min = 2
à- dire dans ce cas.Évitez la solution
itemgetter()
présentée dans les autres réponses et utilisez plutôtcar il ne demande
import operator
ni à utiliserenumerate
, et il est toujours plus rapide (benchmark ci-dessous) qu'une solution utilisantitemgetter()
.Si vous avez affaire à des tableaux numpy ou si vous pouvez vous permettre
numpy
une dépendance, envisagez également d'utiliserCe sera plus rapide que la première solution même si vous l'appliquez à une liste Python pure si:
numpy
tableaucomme l'indique cette référence:
J'ai exécuté le benchmark sur ma machine avec python 2.7 pour les deux solutions ci-dessus (bleu: python pur, première solution) (rouge, solution numpy) et pour la solution standard basée sur
itemgetter()
(noir, solution de référence). Le même benchmark avec python 3.5 a montré que les méthodes comparent exactement la même chose que le cas python 2.7 présenté ci-dessusla source
xrange()
est désormais obsolète, vous pouvez utiliserrange()
import numpy as np; x = [2.3, -1.4]; np.argmin(x)
. Vous verrez que celaargmin
fonctionne aussi sur les flotteursVous pouvez trouver l'index et la valeur min / max en même temps si vous énumérez les éléments de la liste, mais effectuez min / max sur les valeurs d'origine de la liste. Ainsi:
De cette façon, la liste ne sera parcourue qu'une seule fois pendant min (ou max).
la source
key=lambda p: p[1]
Si vous voulez trouver l'index de max dans une liste de nombres (ce qui semble être votre cas), je vous suggère d'utiliser numpy:
la source
Une solution plus simple serait peut-être de transformer le tableau de valeurs en un tableau de valeurs, des paires d'index, et d'en prendre le maximum / min. Cela donnerait l'indice le plus grand / le plus petit qui a le max / min (c'est-à-dire que les paires sont comparées en comparant d'abord le premier élément, puis en comparant le deuxième élément si les premiers sont les mêmes). Notez qu'il n'est pas nécessaire de créer réellement le tableau, car min / max autorisent les générateurs en entrée.
la source
Vous donnera le premier indice du minimum.
la source
Je pense que la meilleure chose à faire est de convertir la liste en a
numpy array
et d'utiliser cette fonction:la source
J'étais également intéressé par cela et j'ai comparé certaines des solutions suggérées en utilisant perfplot (un de mes projets ).
Il s'avère que l' argmin de ce numpy ,
est la méthode la plus rapide pour des listes suffisamment grandes, même avec la conversion implicite de l'entrée
list
en anumpy.array
.Code de génération du tracé:
la source
Utilisez un tableau numpy et la fonction argmax ()
la source
Après avoir obtenu les valeurs maximales, essayez ceci:
Beaucoup plus simple que beaucoup d'options.
la source
Je pense que la réponse ci-dessus résout votre problème, mais je pensais partager une méthode qui vous donne le minimum et tous les indices dans lesquels le minimum apparaît.
Cela passe la liste deux fois mais est encore assez rapide. Il est cependant légèrement plus lent que de trouver l'indice de la première rencontre du minimum. Donc, si vous avez besoin d'un seul des minima, utilisez la solution de Matt Anderson , si vous en avez tous besoin, utilisez-la.
la source
Utilisez la fonction numpy du module numpy.where
Pour l'indice de valeur minimale:
Pour l'indice de valeur maximale:
En fait, cette fonction est beaucoup plus puissante. Vous pouvez poser toutes sortes d'opérations booléennes Pour un indice de valeur entre 3 et 60:
la source
argmin()
au lieu de ce que vous avez fait ici.Ceci est tout simplement possible en utilisant le haut-
enumerate()
et lamax()
fonction et l'optionkey
argument de lamax()
fonction et une simple expression lambda:Dans les documents car
max()
il dit que l'key
argument attend une fonction comme dans lalist.sort()
fonction. Voir également le guide de tri .Il en va de même pour
min()
. Btw, il renvoie la première valeur max / min.la source
Supposons que vous ayez une liste telle que:
Les deux méthodes suivantes sont des moyens assez compacts pour obtenir un tuple avec l'élément minimum et son index. Les deux prennent un temps similaire à traiter. Je préfère la méthode zip, mais c'est mon goût.
méthode zip
énumérer la méthode
la source
Tant que vous savez utiliser lambda et l'argument "clé", une solution simple est:
la source
n
il peut être sensiblement plus lent.Aussi simple que cela :
la source
Pourquoi s'embêter à ajouter des indices d'abord puis à les inverser? La fonction Enumerate () n'est qu'un cas particulier d'utilisation de la fonction zip (). Utilisons-le de manière appropriée:
la source
Juste un ajout mineur à ce qui a déjà été dit.
values.index(min(values))
semble renvoyer le plus petit indice de min. Ce qui suit obtient le plus grand indice:La dernière ligne peut être laissée de côté si l'effet secondaire de l'inversion en place n'a pas d'importance.
Pour parcourir toutes les occurrences
Pour des raisons de brièveté. Il est probablement préférable de mettre en cache en
min(values), values.count(min)
dehors de la boucle.la source
reversed(…)
au lieu de….reverse()
est probablement préférable car il ne mute pas et renvoie de toute façon un générateur. Et toutes les occurrences pourraient également êtreminv = min(values); indices = [i for i, v in enumerate(values) if v == minv]
Un moyen simple de trouver les index avec une valeur minimale dans une liste si vous ne voulez pas importer de modules supplémentaires:
Choisissez ensuite par exemple le premier:
la source
N'ont pas assez de représentants pour commenter la réponse existante.
Mais pour https://stackoverflow.com/a/11825864/3920439 réponse
Cela fonctionne pour les entiers, mais ne fonctionne pas pour les tableaux de flottants (au moins en python 3.6)
TypeError: list indices must be integers or slices, not float
la source
https://docs.python.org/3/library/functions.html#max
Si plusieurs éléments sont maximaux, la fonction renvoie le premier rencontré. Ceci est cohérent avec d'autres outils préservant la stabilité du tri tels que
sorted(iterable, key=keyfunc, reverse=True)[0]
Pour obtenir plus que la première, utilisez la méthode de tri.
la source
Et ça:
Il crée un dictionnaire à partir des éléments en
a
tant que clés et de leurs index en tant que valeurs,dict(zip(a,range(len(a))))[max(a)]
renvoie ainsi la valeur qui correspond à la clémax(a)
qui est l'index du maximum dans a. Je suis un débutant en python donc je ne connais pas la complexité de calcul de cette solution.la source