2012-06-28 32 views

回答

33

由於您已經知道如何找到最小值,因此只需將該值送入index()函數即可獲取列表中該值的索引。即,

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

產生

1 

這將返回列表中的最小值的指標。請注意,如果有幾個極小值,它將返回第一個

min():使用單個參數可迭代,返回非空迭代的最小項(如字符串,元組或列表)。使用多個參數,返回最小的參數。

list.index(x): 返回列表中的索引其值爲x的項目。如果沒有這樣的項目,則爲 錯誤。

7

取決於數據的另一種選擇方案:

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

這是(可能)一般更快,因爲開往建堆最有名的最壞情況下的複雜度爲O(n),而比較排序有一個O(nlog(n))最壞情況界限。但是,分析這兩個實現以確保這些數據結構的Python實現與最佳大小範圍一致仍然很好。 – mvanveen

+0

我喜歡這個,因爲它可以在迭代器上工作。 – steveha

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

這類似於@喬恩克萊門茨的答案。他的用法heapq這意味着它可以用來查找多個最小值。他只是顛倒了元組中值的順序,而不是使用itemgetter(),所以他們自然按正確的順序排序。

如果你需要的是一個最小值,這是一個簡單的方法:

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

enumerate()在Python通常的方式來配對從列表中,它們的指標值;它返回一個迭代器,產生如(i, value)這樣的元組,其中value是來自原始序列的值,並且i是該序列內該值的索引。 min()可以帶一個迭代器; key=參數設置爲忽略配對索引值並僅在每個元組內找到最小第二個值(索引1)的函數。

min()返回它找到的最小值的元組,然後我們使用tuple unpacking將值分配給ivalue

所示的例子是一個列表,但這將有包括迭代任何序列工作:

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

注意itemgetter(n)是一個工廠,使得可調用的對象。使用itemgetter(1),您將得到一個可調用的函數,用於返回序列中的第二個項目(索引1)(在本例中爲元組)。你也可以寫一個函數或lambda功能做同樣的事情:

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

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

當然,使用'itemgetter'(至少在CPython中)將代碼從Python執行到C級。 –

+0

@Jon Clements,我不知道按照相反的順序構建元組是否會更快,正如你的答案一樣。 – steveha

+2

我懷疑表現會/應該是一個瓶頸顯着不同 - 雖然我以前已經糾正。從1個月的一段代碼執行到3天 - 我很滿意。困擾了一下,從2分54秒到2分30秒 - 我不能打擾 - 我沒有經營醫院系統,無論如何我都會受到束縛,所以:) –

相關問題