Python - 找到第二小的数字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26779618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 01:00:20  来源:igfitidea点击:

Python - Find second smallest number

python

提问by user2971812

I found this code on this site to find the second largest number:

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

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

Source: Get the second largest number in a list in linear time

来源:在线性时间内获取列表中的第二大数字

Is it possible to modify this code to find the second smallestnumber? So for example

是否可以修改此代码以找到第二小的数字?所以例如

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

采纳答案by Martijn Pieters

The function can indeed be modified to find the second smallest:

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

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

The old version relied on a Python 2 implementation detail that Noneis always sorted before anything else (so it tests as 'smaller'); I replaced that with using float('inf')as the sentinel, as infinity always tests as largerthan any other number. Ideally the original function should have used float('-inf')instead of Nonethere, to not be tied to an implementation detail other Python implementations may not share.

旧版本依赖于 Python 2 实现细节,该细节None总是排在其他任何东西之前(因此它测试为“更小”);我取代了使用float('inf')作为前哨,为无穷大总是测试,更大的比任何其它号码。理想情况下,应该使用原始函数float('-inf')而不是在None那里使用,以免与其他 Python 实现可能不共享的实现细节相关联。

Demo:

演示:

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

Outside of the function you found, it's almost just as efficient to use the heapq.nsmallest()functionto return the two smallest values from an iterable, and from those two pick the second (or last) value:

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

from heapq import nsmallest

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

Like the above implementation, this is a O(N) solution; keeping the heap variant each step takes logK time, but K is a constant here (2)! Whatever you do, do not use sorting; that takes O(NlogN) time.

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

回答by RemcoGerlich

Yes, except that code relies on a small quirk (that raises an exception in Python 3): the fact that Nonecompares as smaller than a number.

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

Another value that works is float("-inf"), which is a number that is smaller than any other number.

另一个有效的值是float("-inf"),它是一个比任何其他数字都小的数字。

If you use that instead of None, and just change -infto +infand >to <, there's no reason it wouldn't work.

如果您使用的,而不是None,只是改变-inf+inf><,没有理由它不会工作。

Edit: another possibility would be to simply write -xin all the comparisons on x, e.g. do if -x <= m1:et cetera.

编辑:另一种可能性是简单地写-x上所有的比较x,例如 do if -x <= m1:et cetera。

回答by gboffi

Here we want to keep an invariant while we scan the list of numbers, for every sublist it must be

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

m1<=m2<={all other elements}

m1<=m2<={all other elements}

the minimum length of a list for which the question (2nd smallest) is sensible is 2, so we establish the invariant examining the first and the second element of the list (no need for magic numbers), next we iterate on all the remaining numbers, maintaining our invariant.

问题(第二小)合理的列表的最小长度是 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

Addendum

附录

BTW, the same reasoning should be applied to the second_largestfunction mentioned by the OP

顺便说一句,同样的推理应该适用于second_largestOP 提到的功能

回答by John La Rooy

Or just use heapq:

或者只是使用heapq

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

second_largest([1, 2, 3, 4])
# Output: 2

回答by enthus1ast

l = [41,9000,123,1337]

# second smallest
sorted(l)[1]
123


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

回答by gented

As per the Python in-built function sorted

根据 Python 内置函数 sorted

sorted(my_list)[0]

gives back the smallest number, and sorted(my_list)[1]does accordingly for the second smallest, and so on and so forth.

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

回答by Lakshaya Maheshwari

I am writing the code which is using recursion to find the second smallest element in a list.

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

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)

You can test it with various input integers.

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

回答by Nita Mandavkar

a = [6,5,4,4,2,1,10,1,2,48]
s = set(a) # used to convert any of the list/tuple to the distinct element and sorted sequence of elements
# Note: above statement will convert list into sets 
print sorted(s)[1] 

回答by Ankan Roy

There is a easy way to do . First sort the list and get the second item from the list.

有一个简单的方法可以做到。首先对列表进行排序并从列表中获取第二项。

def solution(a_list):

    a_list.sort()
    print a_list[1]

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

回答by user3199580

You can use in built function 'sorted'

您可以在内置函数“已排序”中使用

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)