Python - 查找第二个最小的数字

时间:2014-11-06 12:33:41

标签: python

我在这个网站上找到了这个代码来找到第二大数字:

def second_largest(numbers):
    m1, m2 = None, None
    for x in numbers:
        if x >= m1:
            m1, m2 = x, m1
        elif x > m2:
            m2 = x
    return m2

来源:Get the second largest number in a list in linear time

是否可以修改此代码以查找第二个最小号码?例如,

print second_smallest([1, 2, 3, 4])
2

18 个答案:

答案 0 :(得分:11)

callBackFunction

答案 1 :(得分:10)

确实可以修改该函数以找到第二个最小的函数:

def second_smallest(numbers):
    m1, m2 = float('inf'), float('inf')
    for x in numbers:
        if x <= m1:
            m1, m2 = x, m1
        elif x < m2:
            m2 = x
    return m2

旧版本依赖于Python 2实现细节,None总是在其他任何东西之前排序(所以它测试为'较小');我用float('inf')作为哨兵替换了它,因为无穷大总是测试更大比任何其他数字。理想情况下,原始函数应该使用float('-inf')而不是None,而不是绑定到其他Python实现可能不共享的实现细节。

演示:

>>> def second_smallest(numbers):
...     m1, m2 = float('inf'), float('inf')
...     for x in numbers:
...         if x <= m1:
...             m1, m2 = x, m1
...         elif x < m2:
...             m2 = x
...     return m2
... 
>>> print second_smallest([1, 2, 3, 4])
2

在您找到的函数之外,使用heapq.nsmallest() function从迭代中返回两个最小值并从这两个值中选择第二个(或最后一个)值几乎同样有效:

from heapq import nsmallest

def second_smallest(numbers):
    return nsmallest(2, numbers)[-1]

与上述实现类似,这是一个O(N)解决方案;保持堆变量每一步都需要logK时间,但K是常量(2)!无论你做什么,都不要使用排序;需要O(NlogN)时间。

答案 2 :(得分:7)

或者只使用heapq

import heapq
def second_largest(numbers):
    return heapq.nsmallest(2, numbers)[-1]

second_largest([1, 2, 3, 4])
2

答案 3 :(得分:2)

根据Python内置函数sorted

sorted(my_list)[0]

返回最小的数字,sorted(my_list)[1]相应地为第二个最小数字,依此类推。

答案 4 :(得分:1)

您可以使用内置功能&#39; 已排序&#39;

def second_smallest(numbers):

count = 0
l = []
for i in numbers:
    if(i not in l):
        l.append(i)
        count+=1
    if(count==2):
        break

return max(l)

答案 5 :(得分:1)

def second_min_index(ls):
    min_value = min(ls)
    max_value = max(ls)

    # The smallest number changes into the largest.
    for value in ls:
        if value == min_value:
            ls[ls.index(value)] = max_value

    return ls.index(min(ls))

它比sort方法略快,它修改了列表。

答案 6 :(得分:0)

我正在编写使用递归来查找列表中第二个最小元素的代码。

def small(l):
 small.counter+=1;
 min=l[0];

 emp=[]

 for i in range(len(l)):
    if l[i]<min:
        min=l[i]

 for i in range(len(l)):
    if min==l[i]:
     emp.append(i)

 if small.counter==2:
    print "The Second smallest element is:"+str(min)
 else:
   for j in range(0,len(emp)):

     l.remove(min)

   small(l)
small.counter = 0

list=[-1-1-1-1-1-1-1-1-1,1,1,1,1,1]
small(list)

您可以使用各种输入整数进行测试。

答案 7 :(得分:0)

有一种简单的方法。首先对列表进行排序,然后从列表中获取第二项。

def solution(a_list):

    a_list.sort()
    print a_list[1]

solution([1, 2, -8, -2, -10])

答案 8 :(得分:0)

是的,除了代码依赖于一个小怪癖(在Python 3中引发异常):None比较小于数字的事实。

另一个有用的值是float("-inf"),这是一个小于任何其他数字的数字。

如果您使用{而不是None,而只是将-inf更改为+inf而将>更改为<,那么就没有理由不会工作。

编辑:另一种可能性是在-x的所有比较中简单地写x,例如做if -x <= m1:等等。

答案 9 :(得分:0)

def SecondSmallest(x):
    lowest=min(x[0],x[1])
    lowest2 = max(x[0],x[1])
    for item in x:
         if item < lowest:
            lowest2 = lowest
            lowest = item
         elif lowest2 > item and item > lowest:
            lowest2 = item
    return lowest2

SecondSmallest([10,1,-1,2,3,4,5])

答案 10 :(得分:0)

在这里,我们希望在扫描数字列表时保持不变量,对于每个子列表,它必须是

  

m1<=m2<={all other elements}

问题(第二小)合理的列表的最小长度是2,所以我们建立检查列表的第一个和第二个元素的不变量(不需要幻数),然后我们迭代所有剩下的数字,维持我们的不变性。

def second_smaller(numbers):
    # if len(numbers)<2: return None or otherwise raise an exception

    m1, m2 = numbers[:2]
    if m2<m1: m1, m2 = m2, m1

    for x in numbers[2:]:
        if x <= m1:
            m1, m2 = x, m1
        elif x < m2:
            m2 = x
    return m2

<强> 附录

BTW,相同的推理应该适用于OP提到的second_largest函数

答案 11 :(得分:0)

要在列表中找到第二小的元素,可以使用以下方法,该方法将在重复两个或多个元素时起作用。

             temp     depth   acceleration
2019-01-1 -0.218062 -1.215978 -1.674843
2019-02-1 -0.465085 -0.188715  0.241956
2019-03-1 -1.464794 -1.354594  0.635196
2019-04-1  0.103813  0.194349 -0.450041
2019-05-1  0.437921  0.073829  1.346550

答案 12 :(得分:0)

我最喜欢的查找第二个最小数字的方法是,从列表中删除最小的数字,然后打印列表中的最小数字,这将使我返回列表的第二个最小元素。该任务的代码如下:

mylist=[1,2,3,4]
mylist=[x for x in mylist if x!=min(mylist)]  #deletes the min element from the list
print(min(mylist))

答案 13 :(得分:0)

不带排序返回列表中第二个唯一数字的解决方案:

def sec_smallest(numbers):
    smallest = float('+inf')
    small = float('+inf')
    for i in numbers:
        if i < smallest:
            small = smallest
            smallest = i
        elif i < small and i != smallest:
            small = i
    return small

print('Sec_smallest:', sec_smallest([1, 2, -8, -8, -2, 0]))

答案 14 :(得分:0)

 mi= min(input_list)
    second_min = float('inf')
    for i in input_list:
        if i != mi:
            if i<second_min:
                second_min=i
    if second_min == float('inf'):
        print('not present')
    else:
        print(second_min)
             

##input_list = [6,6,6,6,6]
#input_list = [3, 1, 4, 4, 5, 5, 5, 0, 2, 2]
#input_list = [7, 2, 0, 9, -1, 8]
# Even if there is same number in the list then Python will not get confused.

答案 15 :(得分:-1)

l = [41,9000,123,1337]

# second smallest
sorted(l)[1]
123


# second biggest
sorted(l)[-2]
1337

答案 16 :(得分:-1)

这里是:

<p>

输入:[1、1、1、2]
输出:2

答案 17 :(得分:-1)

此代码也可以正常工作,以查找列表中第二小的数字。 对于此代码,首先我们必须对列表中的值进行排序。之后我们必须将变量初始化为第二个索引。

l1 = [12,32,4,34,64,3,43]
for i in range(0,len(l1)):
       for j in range(0,i+1):
          if l1[i]<l1[j]:
              l1[i],l1[j]=l1[j],l1[i]
min_val = l1[1]
for k in l1:
   if min_val>k:
       break
print(min_val)