it-swarm.com.de

Abrufen des Index des zurückgegebenen max- oder min-Elements mithilfe von max ()/min () in einer Liste

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.

315
Kevin Griffin
 wenn isMinLevel: 
 Rückgabewerte.index (min (Werte)) 
 else: 
 Rückgabewerte.index (max (Werte)) 
268
too much php

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:

  • es ist größer als ein paar Elemente (ungefähr 2 ** 4 Elemente auf meiner Maschine)
  • sie können sich die Speicherkopie von einer reinen Liste in ein numpy-Array leisten

wie dieser Benchmark darauf hinweist:  enter image description here

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

351
gg349

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.

303
Matt Anderson

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)
99
dr.haz

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)
33
Ant6n
list=[1.1412, 4.3453, 5.8709, 0.1314]
list.index(min(list))

Gibt Ihnen den ersten Mindestindex.

22
Andy

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.

 enter image description here


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,
    )
9
Nico Schlömer

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])
6
Ishan Tomar

Nachdem Sie die Maximalwerte erhalten haben, versuchen Sie Folgendes:

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

Viel einfacher als viele Optionen.

5
alpha_989

Verwenden Sie ein Numpy-Array und die Funktion argmax ()

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

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.

4
Simon Hänisch

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 ] )
4
Veiga

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.

4

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.

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)

methode aufzählen

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)
4
Pablo MPA

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)
3
sophist

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.

2
hyperbolic

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]
2
antoninstuppa

Ich denke, am besten konvertieren Sie die Liste in einen numpy array und verwenden diese Funktion: 

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

So einfach ist das :

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

index = stuff.index(max(stuff))
1
dctremblay

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

1
user3920439

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)]
0
The Demz