Frage

Ich verwende Python max und min Funktionen auf Listen für einen Minimax-Algorithmus, und ich brauche den Index des Wertes von max() oder min() zurückgegeben. Mit anderen Worten, muß ich wissen, was den max erzeugt bewegen (bei einer Umdrehung des ersten Spielers) oder min (zweiter Spieler) Wert.

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, die tatsächliche Index des min oder max-Wert zurückzukehren, nicht nur den Wert.

War es hilfreich?

Lösung

if isMinLevel:
    return values.index(min(values))
else:
    return values.index(max(values))

Andere Tipps

Sagen Sie, dass Sie eine Liste values = [3,6,1,5] haben, und müssen den Index des kleinsten Elements, das heißt index_min = 2 in diesem Fall.

Vermeiden Sie die Lösung mit itemgetter() in den anderen Antworten präsentiert, und verwenden Sie stattdessen

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

, weil es erfordert nicht zu import operator noch zu verwenden enumerate, und es ist immer schneller (Benchmark unten) als eine Lösung mit itemgetter().

Wenn Sie mit numpy Arrays handeln oder numpy als Abhängigkeit leisten, sollten Sie auch mit

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

Dies wird schneller sein als die erste Lösung, auch wenn Sie es auf eine reine Python-Liste anwenden, wenn:

  • ist größer als ein paar Elemente (etwa 2 ** 4 Elemente auf meiner Maschine)
  • können Sie die Speicherkopie von einer reinen Liste in einer numpy Array leisten

als Benchmark Punkte aus: Geben Sie hier image description „ loading=

(: Purer Python, erste Lösung blau) (rot, numpy Lösung) und für die Standardlösung auf Basis von itemgetter() (schwarz, Referenzlösung)

Ich habe die Benchmark auf meinem Rechner mit Python 2.7 für die beiden Lösungen, die oben laufen. Das gleiche Benchmark mit Python 3.5 hat gezeigt, dass die Methoden zu vergleichen, genau gleich der Fall Python 2.7 präsentiert oben

Sie können den Min / Max-Index und den Wert zur gleichen Zeit finden, wenn Sie die Elemente in der Liste aufzählen, aber führen min / max auf die ursprünglichen Werte in der Liste. Wie so:

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) verfahren werden.

Wenn Sie den Index von max innerhalb einer Liste von Zahlen finden wollen (die Ihren Fall scheint), dann schlage ich Sie verwenden numpy:

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

Möglicherweise eine einfachere Lösung wäre es, die Anordnung von Werten in ein Array von Wert zu drehen, Index-Paaren, und nimmt den max / min von dem. Dies würde den größten / kleinsten Index geben, die die max / min hat (d.h. Paaren verglichen werden, indem zuerst das erste Element zu vergleichen, und dann das zweite Element zu vergleichen, wenn die ersten, die die gleichen sind). Beachten Sie, dass es nicht notwendig ist, um tatsächlich das Array zu erstellen, weil min / max Generatoren als Eingabe ermöglichen.

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 ersten Index von Minimum.

Ich war auch daran interessiert und einige der vorgeschlagenen Lösungen verglichen mit perfplot (ein Lieblingsprojekt von Mine).

Es stellte sich heraus, dass numpy ist argmin ,

numpy.argmin(x)

ist die schnellste Methode für groß genug, um Listen, auch mit der impliziten Konvertierung vom Eingang list zu einem numpy.array.

 image description hier

eingeben

-Code zur Erzeugung der Handlung:

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,
    )

Mit einem numpy Array und die argmax () Funktion

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

Nachdem Sie die Maximalwerte zu erhalten, versuchen Sie dies:

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

Viel einfacher als viele Optionen.

Ich denke, das Beste ist, um die Liste zu einem numpy array konvertieren zu tun, und verwenden Sie diese Funktion:

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

Ich denke, die Antwort über Ihr Problem löst, aber ich dachte, ich würde ein Verfahren teilen, dass Sie das Minimum und alle die Indizes die Mindest erscheint in.

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

Dieser übergibt die Liste zweimal, aber immer noch recht schnell. Es ist jedoch etwas langsamer als der Index der ersten Begegnung des Minimums zu finden. Also, wenn Sie nur eine der Minima benötigen, verwenden Sie Matt Anderson 's Lösung, wenn Sie müssen sie alle, diese verwenden.

Mit numpy Moduls Funktion numpy.where

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

Für Index Minimalwert:

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

Für Index Maximalwert:

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

In der Tat, diese Funktion ist viel mächtiger. Sie können alle Arten von Boolesche Operationen darstellen Für Index des Wertes 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])

Dies ist einfach möglich mit dem eingebauten in enumerate() und max() Funktion und das optionalen key Argument der max() Funktion und ein einfachen Lambda-Ausdruck:

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

In der Dokumentation für max() heißt es, dass das Argument key erwartet eine Funktion wie in der list.sort() Funktion. Siehe auch den Sortierung Wie .

Es funktioniert genauso für min(). Btw gibt sie den ersten max / min-Wert.

Solange Sie wissen, wie Lambda zu verwenden und das „Schlüssel“ Argument, eine einfache Lösung:

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

Angenommen, Sie haben eine Liste wie:

a = [9,8,7]

Die folgenden beiden Methoden sind ziemlich kompakt Möglichkeiten, um ein Tupel mit dem minimalen Elemente und seinem Index zu erhalten. Beide nehmen eine ähnlich Zeit zu verarbeiten. Ich besser wie die Zip-Methode, aber das ist mein Geschmack.

zip Methode

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)

enumerate Methode

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 sich die Mühe Indizes zuerst hinzufügen und sie dann umkehren? Aufzählen () Funktion ist nur ein Spezialfall von zip () Funktion Nutzung. Lassen Sie uns es verwenden, auf passende Art:

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 Zugabe zu dem, was bereits gesagt worden. values.index(min(values)) scheint den kleinsten Index von min zurückzukehren. Im Folgenden wird der größte Index:

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

Die letzte Zeile weggelassen werden kann, wenn die Nebenwirkung des an Ort und Stelle umgekehrt spielt keine Rolle.

Um Iterierte durch alle Vorkommen

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

Aus Gründen der Kürze. Es ist wahrscheinlich eine bessere Idee zu Cache min(values), values.count(min) außerhalb der Schleife.

Eine einfache Art und Weise die Indizes mit einem minimalen Wert in einer Liste für die Suche, wenn Sie nicht möchten, zusätzliche Module importieren:

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

Wählen Sie dann zum Beispiel des ersten:

choosen = indexes_with_min_value[0]

So einfach ist das:

stuff = [2, 4, 8, 15, 11]

index = stuff.index(max(stuff))

Ich habe keine hoch genug rep zu kommentieren bestehende Antwort.

Aber für https://stackoverflow.com/a/11825864/3920439 Antwort

Dies funktioniert für ganze Zahlen, aber nicht funktioniert für Array von Schwimmern (zumindest in Python 3.6) Es wird erhöhen TypeError: list indices must be integers or slices, not float

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

Wenn Sie mehr Artikel maximal sind, gibt die Funktion den ersten angetroffen. Dies steht im Einklang mit anderer Art Stabilität zu bewahren Tool wie sorted(iterable, key=keyfunc, reverse=True)[0]

Um mehr als nur der erste Gebrauch 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)]
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top