Ich verwende die Python-Funktionen max
und min
in Listen für einen Minimax-Algorithmus und brauche den Index des von max()
oder min()
zurückgegebenen Werts. Mit anderen Worten, ich muss wissen, welcher Zug den maximalen (beim ersten Spielerzug) oder min (zweiten Spieler) Wert erzeugt hat.
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)
Ich muss in der Lage sein, den tatsächlichen Index des min- oder max-Werts zurückzugeben, nicht nur den Wert.
wenn isMinLevel: Rückgabewerte.index (min (Werte)) else: Rückgabewerte.index (max (Werte))
Angenommen, Sie haben eine Liste values = [3,6,1,5]
und benötigen in diesem Fall den Index des kleinsten Elements, d. H. index_min = 2
.
Vermeiden Sie die Lösung mit itemgetter()
in den anderen Antworten und verwenden Sie stattdessen
index_min = min(xrange(len(values)), key=values.__getitem__)
weil es nicht erforderlich ist, import operator
zu verwenden oder enumerate
zu verwenden, und es ist immer schneller (Benchmark unten) als eine Lösung, die itemgetter()
verwendet.
Wenn Sie mit numpy-Arrays zu tun haben oder numpy
als Abhängigkeit anbieten können, sollten Sie dies auch in Betracht ziehen
import numpy as np
index_min = np.argmin(values)
Dies ist schneller als die erste Lösung, auch wenn Sie es auf eine reine Python-Liste anwenden, wenn:
numpy
-Array leistenwie dieser Benchmark darauf hinweist:
Ich habe den Benchmark auf meinem Rechner mit Python 2.7 für die beiden obigen Lösungen (blau: reines Python, erste Lösung) (rote, numpy-Lösung) und für die Standardlösung auf der Basis von itemgetter()
(schwarz, Referenzlösung) Dasselbe Benchmarking mit Python 3.5 zeigte, dass die Methoden genau das gleiche wie der oben dargestellte Python 2.7-Fall darstellen
Sie können den min/max-Index und den Wert gleichzeitig ermitteln, wenn Sie die Elemente in der Liste auflisten, aber min/max mit den ursprünglichen Werten der Liste durchführen. So wie:
import operator
min_index, min_value = min(enumerate(values), key=operator.itemgetter(1))
max_index, max_value = max(enumerate(values), key=operator.itemgetter(1))
Auf diese Weise wird die Liste nur einmal für min (oder max) durchlaufen.
Wenn Sie den Index von max in einer Liste von Zahlen finden möchten (was Ihr Fall zu sein scheint), dann schlage ich vor, dass Sie numpy verwenden:
import numpy as np
ind = np.argmax(mylist)
Eine einfachere Lösung wäre möglicherweise, das Array von Werten in ein Array von Wert-Index-Paaren umzuwandeln und die Max/Min-Werte davon zu nehmen. Dies würde den größten/kleinsten Index ergeben, der max/min hat (d. H. Paare werden verglichen, indem zuerst das erste Element und dann das zweite Element verglichen werden, wenn die ersten gleich sind). Beachten Sie, dass das Array nicht unbedingt erstellt werden muss, da min/max Generatoren als Eingabe zulässt.
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))
Gibt Ihnen den ersten Mindestindex.
Ich interessierte mich auch dafür und verglich einige der vorgeschlagenen Lösungen mit perfplot (einem meiner Lieblingsprojekte).
Stellt sich heraus, dass numpys argmin ,
numpy.argmin(x)
ist die schnellste Methode für ausreichend große Listen, selbst bei der impliziten Konvertierung von der Eingabe list
in einen numpy.array
.
Code zum Erzeugen des Diagramms:
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,
)
Verwenden Sie die Funktion numpy.where von numpy module
import numpy as n
x = n.array((3,3,4,7,4,56,65,1))
Für den Index des Mindestwerts:
idx = n.where(x==x.min())[0]
Für den Index des Maximalwerts:
idx = n.where(x==x.max())[0]
Tatsächlich ist diese Funktion viel leistungsfähiger. Sie können alle Arten von booleschen Operationen stellen. Für einen Wertindex zwischen 3 und 60:
idx = n.where((x>3)&(x<60))[0]
idx
array([2, 3, 4, 5])
x[idx]
array([ 4, 7, 4, 56])
Nachdem Sie die Maximalwerte erhalten haben, versuchen Sie Folgendes:
max_val = max(list)
index_max = list.index(max_val)
Viel einfacher als viele Optionen.
Verwenden Sie ein Numpy-Array und die Funktion argmax ()
a=np.array([1,2,3])
b=np.argmax(a)
print(b) #2
Dies ist einfach mit der integrierten Funktion enumerate()
und max()
und dem optionalen Argument key
der Funktion max()
und einem einfachen Lambda-Ausdruck möglich:
theList = [1, 5, 10]
maxIndex, maxValue = max(enumerate(theList), key=lambda v: v[1])
# => (2, 10)
In den Dokumenten für max()
heißt es, dass das Argument key
eine Funktion wie in der Funktion list.sort()
erwartet. Siehe auch Sorting How To .
Es funktioniert genauso für min()
. Übrigens gibt es den ersten Max/Min-Wert zurück.
Solange Sie wissen, wie Lambda und das Schlüsselargument verwendet werden, ist eine einfache Lösung:
max_index = max( range( len(my_list) ), key = lambda index : my_list[ index ] )
Ich denke, die Antwort oben löst Ihr Problem, aber ich dachte, ich würde eine Methode teilen, die Ihnen das Minimum gibt und alle Indizes, in denen das Minimum erscheint.
minval = min(mylist)
ind = [i for i, v in enumerate(mylist) if v == minval]
Dies führt die Liste zweimal durch, ist aber immer noch recht schnell. Es ist jedoch etwas langsamer als der Index des ersten Auftretens des Minimums. Wenn Sie also nur eines der Minima benötigen, verwenden Sie die Lösung von Matt Anderson . Wenn Sie sie alle benötigen, verwenden Sie diese Option.
Angenommen, Sie haben eine Liste wie:
a = [9,8,7]
Die folgenden zwei Methoden sind ziemlich kompakte Methoden, um ein Tuple mit dem Minimumelement und seinem Index zu erhalten. Beide benötigen eine ähnliche Zeit für die Verarbeitung. Ich mag die Zip-Methode besser, aber das ist mein Geschmack.
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)
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)
Warum erst die Indizes hinzufügen und dann umkehren? Die Enumerate () - Funktion ist nur ein Spezialfall der Verwendung der Zip () - Funktion. Lass es uns angemessen verwenden:
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)
Nur eine kleine Ergänzung zu dem, was bereits gesagt wurde .values.index(min(values))
scheint den kleinsten Index von min zurückzugeben. Folgendes erhält den größten Index:
values.reverse()
(values.index(min(values)) + len(values) - 1) % len(values)
values.reverse()
Die letzte Zeile kann weggelassen werden, wenn der Nebeneffekt der Umkehrung keine Rolle spielt.
Durchlaufen aller Vorkommen
indices = []
i = -1
for _ in range(values.count(min(values))):
i = values[i + 1:].index(min(values)) + i + 1
indices.append(i)
Um es kurz zu machen. Es ist wahrscheinlich eine bessere Idee, min(values), values.count(min)
außerhalb der Schleife zu cachen.
Eine einfache Methode zum Auffinden der Indizes mit minimalem Wert in einer Liste, wenn Sie keine zusätzlichen Module importieren möchten:
min_value = min(values)
indexes_with_min_value = [i for i in range(0,len(values)) if values[i] == min_value]
Dann wählen Sie zum Beispiel den ersten:
choosen = indexes_with_min_value[0]
Ich denke, am besten konvertieren Sie die Liste in einen numpy array
und verwenden diese Funktion:
a = np.array(list)
idx = np.argmax(a)
So einfach ist das :
stuff = [2, 4, 8, 15, 11]
index = stuff.index(max(stuff))
Sie haben keine ausreichende Wiederholungsrate, um die vorhandene Antwort zu kommentieren.
Aber für https://stackoverflow.com/a/11825864/3920439 answer
Dies funktioniert für Ganzzahlen, aber nicht für Float-Arrays (zumindest in Python 3.6) .__ TypeError: list indices must be integers or slices, not float
https://docs.python.org/3/library/functions.html#max
Wenn mehrere Elemente maximal sind, gibt die Funktion den zuerst gefundenen zurück. Dies steht im Einklang mit anderen Sortenstabilitäts-Tools wie sorted(iterable, key=keyfunc, reverse=True)[0]
.
Um mehr als nur die erste zu erhalten, verwenden Sie die Sortiermethode.
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)]