Używam Pythona max
i min
funkcji na listach dla algorytmu minimax i potrzebuję indeksu wartości zwróconej przez max()
lub min()
. Innymi słowy, muszę wiedzieć, który ruch wytworzył wartość maksymalną (podczas tury pierwszego gracza) lub wartość minimalną (drugiego gracza).
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)
Muszę być w stanie zwrócić rzeczywisty indeks wartości minimalnej lub maksymalnej, a nie tylko wartość.
divmod
istnieje, aby nie musieć[i / 3, i % 3]
wiele mówić .Odpowiedzi:
źródło
tmp = min(values); return values.index(tmp)
Powiedz, że masz listę
values = [3,6,1,5]
i potrzebujesz indeksu najmniejszego elementu, czyliindex_min = 2
w tym przypadku.Unikaj rozwiązania
itemgetter()
przedstawionego w innych odpowiedziach i użyj zamiast tegoponieważ nie wymaga
import operator
ani nie używaenumerate
, i zawsze jest szybszy (benchmark poniżej) niż rozwiązanieitemgetter()
.Jeśli masz do czynienia z tablicami numpy lub możesz sobie pozwolić
numpy
na zależność, rozważ również użycieBędzie to szybsze niż pierwsze rozwiązanie, nawet jeśli zastosujesz go do czystej listy Python, jeśli:
numpy
tablicyjak wskazuje ten punkt odniesienia:
Uruchomiłem test porównawczy na moim komputerze z Pythonem 2.7 dla dwóch powyższych rozwiązań (niebieski: czysty python, pierwsze rozwiązanie) (czerwony, numpy) i dla standardowego rozwiązania opartego na
itemgetter()
(czarny, rozwiązanie referencyjne). Ten sam test porównawczy z python 3.5 pokazał, że metody porównują dokładnie to samo z powyższym przypadkiem python 2.7źródło
xrange()
jest już nieaktualny, możesz go używaćrange()
import numpy as np; x = [2.3, -1.4]; np.argmin(x)
. Zobaczysz, żeargmin
działa również na pływakachMożesz znaleźć indeks i wartość min / max w tym samym czasie, jeśli wyliczysz pozycje na liście, ale wykonasz min / max na oryginalnych wartościach listy. Tak jak:
W ten sposób lista będzie przeglądana tylko raz przez min (lub max).
źródło
key=lambda p: p[1]
Jeśli chcesz znaleźć indeks maksymalny na liście liczb (co wydaje się twoim przypadkiem), sugeruję użycie numpy:
źródło
Być może prostszym rozwiązaniem byłoby przekształcenie tablicy wartości w tablicę wartości, pary indeksów i przyjęcie jej maksimum / min. Dałoby to największy / najmniejszy indeks, który ma maksimum / min (tzn. Pary są porównywane najpierw przez porównanie pierwszego elementu, a następnie porównanie drugiego elementu, jeśli pierwsze są takie same). Zauważ, że nie jest konieczne tworzenie tablicy, ponieważ min / max zezwalają na generatory jako dane wejściowe.
źródło
Otrzymasz pierwszy indeks minimum.
źródło
Myślę, że najlepiej jest przekonwertować listę na
numpy array
i użyć tej funkcji:źródło
Byłem również tym zainteresowany i porównałem niektóre z sugerowanych rozwiązań za pomocą perfplot ( projektu dla zwierząt domowych).
Okazuje się, że argmin tego numpy ,
jest najszybszą metodą dla wystarczająco dużych list, nawet z niejawną konwersją z danych wejściowych
list
na anumpy.array
.Kod do generowania wykresu:
źródło
Użyj tablicy numpy i funkcji argmax ()
źródło
Po uzyskaniu maksymalnych wartości spróbuj wykonać następujące czynności:
Znacznie prostsze niż wiele opcji.
źródło
Myślę, że powyższa odpowiedź rozwiązuje twój problem, ale pomyślałem, że podzielę się metodą, która daje ci minimum i wszystkie wskaźniki, w których pojawia się minimum.
To mija listę dwa razy, ale wciąż jest dość szybkie. Jest jednak nieco wolniejszy niż znalezienie wskaźnika pierwszego spotkania minimum. Więc jeśli potrzebujesz tylko jednego minimum, skorzystaj z rozwiązania Matta Andersona , jeśli potrzebujesz ich wszystkich, skorzystaj z tego.
źródło
Użyj funkcji numpy modułu numpy.where
Dla indeksu wartości minimalnej:
Dla indeksu wartości maksymalnej:
W rzeczywistości ta funkcja jest znacznie potężniejsza. Możesz tworzyć wszelkiego rodzaju operacje boolowskie. Dla indeksu wartości od 3 do 60:
źródło
argmin()
zamiast tego, co tutaj zrobiłeś.To jest po prostu możliwe przy użyciu wbudowanych
enumerate()
imax()
funkcji i opcjonalnegokey
argumentumax()
funkcji i prostego wyrażenia lambda:W dokumentacji
max()
napisano, żekey
argument oczekuje funkcji takiej jak wlist.sort()
funkcji. Zobacz także Sortowanie .Działa to samo dla
min()
. Btw zwraca pierwszą wartość maks./min.źródło
Powiedz, że masz listę, taką jak:
Poniższe dwie metody to dość kompaktowe sposoby uzyskania krotki z minimalnym elementem i jego indeksem. Oba mają podobne czas do przetworzenia. Bardziej podoba mi się metoda zip, ale taki jest mój gust.
metoda zip
wyliczyć metodę
źródło
Tak długo, jak wiesz, jak używać lambda i argumentu „klucz”, proste rozwiązanie to:
źródło
n
może być zauważalnie wolniejsze.Proste :
źródło
Po co zawracać sobie głowę dodawaniem indeksów, a następnie ich odwracaniem? Funkcja Enumerate () jest tylko specjalnym przypadkiem użycia funkcji zip (). Użyjmy go w odpowiedni sposób:
źródło
Tylko drobny dodatek do tego, co już powiedziano.
values.index(min(values))
wydaje się zwracać najmniejszy indeks min. Największy indeks otrzymuje następujący:Ostatni wiersz można pominąć, jeśli efekt uboczny cofnięcia w miejscu nie ma znaczenia.
Aby iterować przez wszystkie wystąpienia
Ze względu na zwięzłość. Prawdopodobnie lepszym pomysłem jest buforowanie
min(values), values.count(min)
poza pętlą.źródło
reversed(…)
zamiast….reverse()
jest prawdopodobnie preferowane, ponieważ i tak nie mutuje i zwraca generator. I wszystkie zdarzenia mogą być równieżminv = min(values); indices = [i for i, v in enumerate(values) if v == minv]
Prosty sposób na znalezienie indeksów o minimalnej wartości na liście, jeśli nie chcesz importować dodatkowych modułów:
Następnie wybierz na przykład pierwszy:
źródło
Nie masz wystarczająco wysokiego przedstawiciela, aby skomentować istniejącą odpowiedź.
Ale dla https://stackoverflow.com/a/11825864/3920439 odpowiedź
Działa to dla liczb całkowitych, ale nie działa dla tablicy liczb zmiennoprzecinkowych (przynajmniej w Pythonie 3.6)
TypeError: list indices must be integers or slices, not float
źródło
https://docs.python.org/3/library/functions.html#max
Jeśli maksymalna liczba elementów jest maksymalna, funkcja zwraca pierwszy napotkany. Jest to zgodne z innymi narzędziami zabezpieczającymi stabilność sortowania, takimi jak
sorted(iterable, key=keyfunc, reverse=True)[0]
Aby uzyskać więcej niż tylko pierwszą, użyj metody sortowania.
źródło
A co z tym:
It creates a dictionary from the items in
a
as keys and their indexes as values, thusdict(zip(a,range(len(a))))[max(a)]
returns the value that corresponds to the keymax(a)
which is the index of the maximum in a. I'm a beginner in python so I don't know about the computational complexity of this solution.źródło