簡體   English   中英

在列表中查找包含重復元素的第二大元素

[英]Find second largest element in list with repeated elements

我有一個列表,其中故意設置了幾個非常大的值以區分那些索引,看起來像這樣:

a = [1.3, 2.1, 9999., 5., 3.7 ,6.6, 9999., 7.4, 9999., 3.5, 7, 1.2, 9999.]

我需要以盡可能最有效的方式在該列表中找到第二個最大值,該最大值等於9999. (在上述情況下為7.4 )(我的列表會變得很大)

在此問題中,從包含100,000個整數列表中檢索出兩個最高的項目,但提到了heapq.nlargest函數,但是由於我有多個值9999.所以它將不起作用。

這是另一種方法:

>>> a = [1.3, 2.1, 9999., 5., 3.7 ,6.6, 9999., 7.4, 9999., 3.5, 7, 1.2, 9999.]
>>> sorted(set(a))[-2]
7.4
>>>

而且,信不信由你,它實際上比公認的解決方案快很多:

>>> from timeit import timeit
>>> timeit("a=range(10000000);print sorted(set(a))[-2]", number=10)
9999998
9999998
9999998
9999998
9999998
9999998
9999998
9999998
9999998
9999998
34.327036257401424
>>> # This is NPE's answer
>>> timeit("a=range(10000000);maxa = max(a);print max(val for val in a if val != maxa)", number=10)
9999998
9999998
9999998
9999998
9999998
9999998
9999998
9999998
9999998
9999998
53.22811809880869
>>>

上面的測試可以運行10次,並且可以處理包含10,000,000個項目的列表。 除非測試中存在缺陷(我認為沒有缺陷),否則我提供的解決方案顯然要快得多。

>>> max(val for val in a if val != 9999)
7.4

這具有O(n)時間復雜度。

如果9999不是固定的,則可以使用max(a)而不是9999來泛化它:

>>> maxa = max(a)
>>> max(val for val in a if val != maxa)
7.4

(盡管我懷疑這不是您想要的。)

a = set([1.3, 2.1, 9999., 5., 3.7 ,6.6, 9999., 7.4, 9999., 3.5, 7, 1.2, 9999.])
a.remove(max(a))
print max(a)

這使用set來確保我們只處理唯一的項目,然后刪除最大值,以便下次調用max ,將剩下第二個最佳最大值。

如果要使用numpy,則可以使用掩碼數組跳過“錯誤”值:

import numpy as np
a = np.array([1.3, 2.1, 9999., 5., 3.7 ,6.6, 9999., 7.4, 9999., 3.5, 7, 1.2, 9999.])
ma = np.ma.masked_values(a, 9999., copy=False)
ma.max()
7.4

您可以輕松地將排除項添加到蒙版中:

ma = np.ma.masked_values(ma, 7.4, copy=False)
ma.max()
7.0
ma.mask[ma>=5]=True   
ma.max()
3.7

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM