Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查找列表中具有重复元素的第二大元素_Python_List - Fatal编程技术网

Python 查找列表中具有重复元素的第二大元素

Python 查找列表中具有重复元素的第二大元素,python,list,Python,List,我有一个列表,其中有几个非常大的值,用于区分这些索引,如下所示: a = [1.3, 2.1, 9999., 5., 3.7 ,6.6, 9999., 7.4, 9999., 3.5, 7, 1.2, 9999.] 我需要找到列表中第二大的值,它不等于9999.(在上面的例子中,它将是7.4)以最有效的方式(我的列表可能会变得很大) 在这个问题中提到了heapq.nlargest函数,但由于我有多个值9999.它不起作用 >>> max(val for val in a if

我有一个列表,其中有几个非常大的值,用于区分这些索引,如下所示:

a = [1.3, 2.1, 9999., 5., 3.7 ,6.6, 9999., 7.4, 9999., 3.5, 7, 1.2, 9999.]
我需要找到列表中第二大的值,它不等于
9999.
(在上面的例子中,它将是
7.4
)以最有效的方式(我的列表可能会变得很大)

在这个问题中提到了
heapq.nlargest
函数,但由于我有多个值
9999.
它不起作用

>>> max(val for val in a if val != 9999)
7.4
这具有时间复杂性

如果
9999
不固定,您可以使用
max(a)
而不是
9999
来概括这一点:

>>> maxa = max(a)
>>> max(val for val in a if val != maxa)
7.4
(尽管我怀疑这不是你想要的。)

这具有时间复杂性

如果
9999
不固定,您可以使用
max(a)
而不是
9999
来概括这一点:

>>> maxa = max(a)
>>> max(val for val in a if val != maxa)
7.4
(尽管我怀疑这不是你想要的。)

这使用
set
来确保我们只处理唯一的项,然后删除最大值,这样下次调用
max
时,我们将得到第二个最佳最大值


这使用
set
来确保我们只处理唯一的项,然后删除最大值,这样下次调用
max
时,我们将得到第二个最佳最大值。

这里有一个替代方法:

>>> 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次的测试,它使用的是一个包含10000000项的列表。除非我的测试中存在缺陷(我认为没有),否则我给出的解决方案显然要快得多。

这里有一种替代方法:

>>> 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次的测试,它使用的是一个包含10000000项的列表。除非我的测试中存在缺陷(我认为没有),否则我给出的解决方案显然要快得多。

如果您想使用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

如果要使用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

如果val!=max(a)
只需确保为发电机呼叫
max(a)
外部。或者
如果val!=最大值(a)
只需确保调用发电机外部的
max(a)
。第二大值,或最大值不等于9999?最大值不等于9999。我称之为第二大,因为我认为所有9999个值都是一样的,但这可能有点让人困惑。我应该编辑问题的名称吗?第二大,还是最大不等于9999?最大不等于9999。我称之为第二大,因为我认为所有9999个值都是一样的,但这可能有点让人困惑。我应该编辑问题的名称吗?我简直不敢相信!但这对我也有好处+1现在!也许
range()
给出了一个已经排序的列表,因此是不“公平的”?我还尝试了
a=[I%10代表范围内的I(1000000)]并得到相同的结果。有趣。@AaronMcDaid-无论列表是否排序,Python都必须检查它。毕竟,计算机是如何知道它的分类的?我想我说的是对的,计算机不能,所以它会对列表进行排序。另外,我也给了NPE一个排序列表,所以一切都是公平的。通常人们说快速排序的复杂性是N log N,但这只是平均值。如果数据是以一种非常糟糕的方式排序的,那么复杂度就会跳到N^2。或者它可以是O(N)在已经按正确顺序排列的数据上(但这取决于)。所以,是的,正如你所说,它必须对它进行排序。问题在于,在人工数据集上完成排序的速度可能比在随机数据集上快得多。很好,我已经将公认的答案改为这一个,因为性能是问题的中心,这是性能最好的一个。谢谢大家!!真不敢相信!但这对我也有好处+1现在!也许
range()
给出了一个已经排序的列表,因此是不“公平的”?我还尝试了
a=[I%10代表范围内的I(1000000)]并得到相同的结果。有趣。@AaronMcDaid-无论列表是否排序,Python都必须检查它。毕竟,计算机是如何知道它的分类的?我想我说的是对的,计算机不能,所以它会对列表进行排序。另外,我也给了NPE一个排序列表,所以一切都是公平的。通常人们说快速排序的复杂性是N log N,但这只是平均值。如果数据是以一种非常糟糕的方式排序的,那么复杂度就会跳到N^2。或者它可以是O(N)在已经按正确顺序排列的数据上(但这取决于)。所以,是的,正如你所说,它必须对它进行排序。问题在于,在人工数据集上完成排序的速度可能比在随机数据集上快得多。很好,我已经将公认的答案改为这一个,因为性能是问题的中心,这是性能最好的一个。谢谢大家!!