2012-06-28 12 views

Odpowiedz

33

Ponieważ już wiesz, jak znaleźć minimalną wartość, po prostu przekazujesz tę wartość do funkcji index(), aby uzyskać indeks tej wartości na liście. Tj,

n = [20, 15, 27, 30] 
n.index(min(n)) 

daje

1 

To zwróci indeks minimalnej wartości na liście. Zauważ, że jeśli istnieje kilka minimów, zwróci on najpierw.

min(): Za pomocą pojedynczego argumentu iterowalnego zwracamy najmniejszy element niepustej iteracji (takiej jak łańcuch, krotka lub lista). W przypadku więcej niż jednego argumentu zwróć najmniejszy z argumentów.

list.index(x): Zwraca indeks na liście pozycji pierwszy którego wartość wynosi x. Jest błąd, jeśli nie ma takiego elementu.

7

Inną opcją w zależności od złożoności danych:

import heapq 
s = [20, 15, 27, 30] 
heapq.nsmallest(1, ((k, i) for i, k in enumerate(s))) 
+1

Jest to (prawdopodobnie) szybciej w ogóle, ponieważ najlepiej znany najgorszym przypadku złożoność związany na budowanie sterty wynosi O (n), natomiast porównania sorts mają powiązany najgorszy przypadek O (nlog (n)). Jednak nadal dobrze byłoby profilować te dwie implementacje, aby zapewnić, że implementacje Pythona tych struktur danych są zgodne z najlepszymi możliwymi ramami. – mvanveen

+0

Podoba mi się to, ponieważ działa na iteratorze. – steveha

10
>>> L = [20, 15, 27, 30] 
>>> min(range(len(L)), key=L.__getitem__) 
1 
5

ta jest podobna do odpowiedzi @Jon Clements za. Jego zastosowanie to heapq, co oznacza, że ​​można go wykorzystać do znalezienia więcej niż jednej najmniejszej wartości. Zamiast używać itemgetter() po prostu odwraca kolejność wartości w krotkach, aby naturalnie sortować we właściwej kolejności.

Jeśli wszystko czego potrzebujesz to pojedynczy najmniejszą wartość, jest to prosty sposób:

from operator import itemgetter 
lst = [20, 15, 27, 30] 
i, value = min(enumerate(lst), key=itemgetter(1)) 

enumerate() jest zwykły sposób w Pythonie, aby powiązać się wartości z listy i ich indeksów; zwraca iterator, który daje krotki, takie jak (i, value), gdzie value jest wartością z oryginalnej sekwencji, a i jest indeksem tej wartości w sekwencji. min() może przyjąć iterator; Argument key= jest ustawiony na funkcję, która ignoruje wartość indeksu sparowanego i po prostu znajduje minimalną drugą wartość (indeks 1) w obrębie każdej krotki.

min() zwraca krotkę znalezioną z wartością min, a następnie używamy rozpakowywania krotek, aby przypisać wartości do i i value.

Przykład pokazany jest lista, ale to będzie działać z każdą sekwencją tym iteratora:

from random import randint 
def rseq(n=20): 
    for i in xrange(n): 
     yield randint(0, 101) 

i, value = min(enumerate(rseq()), key=itemgetter(1)) 

Zauważ, że itemgetter(n) jest fabryka, która sprawia wywołalnych obiektów. Z itemgetter(1) otrzymasz wywołanie, które zwraca drugą pozycję (indeks 1) w sekwencji (w tym przypadku krotka).Można również napisać funkcję lub lambda funkcji zrobić to samo:

def get1(x): 
    return x[1] 
i, value = min(enumerate(lst), key=get1) 

i, value = min(enumerate(lst), key=lambda x: x[1]) 
+0

Oczywiście, użycie 'itemgetter' (przynajmniej w CPython) powoduje wykonanie kodu z Pythona i na poziom C. –

+0

@Jon Clements, Zastanawiam się, czy szybciej byłoby po prostu zbudować krotki w odwrotnej kolejności, jak to zrobiła twoja odpowiedź. – steveha

+2

Wątpię, żeby wydajność była/powinna być szyjką do butelek znacznie różniącą się od siebie - mimo że wcześniej mnie poprawiono. Biorąc trochę kodu od 1 miesiąca do wykonania do 3 dni - cieszę się. Trochę się przejmuję tym, co trwa od 2 minut 54 do 2 minut 30 - nie przeszkadza mi - nie używam systemów szpitalnych, a mimo to jestem związany z IO, więc :) –

Powiązane problemy