简体   繁体   English

如何找到列表中第二低和第二高的元素?

[英]How to find the second lowest and second highest element in a list?

So, the function works with no errors, but the output for min2(2nd lowest value) in the list is incorrect.因此,function 没有错误,但列表中 min2(第二低值)的 output 不正确。 I cant seem to find the solution.我似乎无法找到解决方案。 Python 3.8.6 Python 3.8.6

def max2min2(list1):
    max1=list1[0]
    min1=list1[0]
    max2=None
    min2=None
    for item in list1:
        if item>max1:
            max2=max1
            max1=item
        elif max2==None or max2<item:
            max2=item
        if item<min1:
            min2=min1
            min1=item
        elif min2==None or min2>item:
            min2=item
    return max2,min2

list1 = [1,2,3]
max2,min2=max2min2(list1)
print(min2,max2) # 1 2

With the simple input list of [1,2,3] the output of maxmin2 is (1,2) , although the expected output is (2,2) .对于[1,2,3]的简单输入列表,maxmin2 的maxmin2(1,2) ,尽管预期的 output 是(2,2)

A simple and readable solution is to sort the list first, then directly index the values you want.一个简单易读的解决方案是先对列表进行排序,然后直接索引你想要的值。 I added a unique argument which specifies whether you want to look at the number values (most intuitive) or keep duplicate values in the list (so that the second highest number in [1,2,2] is 2 ).我添加了一个unique参数,它指定您是要查看数字值(最直观)还是在列表中保留重复值(以便[1,2,2]中的第二大数字是2 )。

def second_lowest_and_highest_using_sort(nums, unique=True):
    if unique:
        nums = list(set(nums))

    if len(nums) == 1:
        raise ValueError('Second lowest/highest number is undefined for a list of length 1.')

    nums = sorted(nums)
    return (nums[1], nums[-2])

A more verbose approach without sorting first:没有先排序的更详细的方法:

def second_lowest_and_highest(nums, unique=True):
    if unique:
        nums = list(set(nums))

    if len(nums) == 1:
        raise ValueError('Second lowest/highest number is undefined for a list of length 1.')

    lowest, highest = float('inf'), float('-inf')
    second_lowest, second_highest = None, None

    low_delta, high_delta = float('inf'), float('inf')

    for num in nums:
        low_delta_new = num - lowest
        if low_delta_new < 0:
            second_lowest = lowest
            lowest = num
        elif low_delta_new <= low_delta:
            second_lowest = num
            low_delta = low_delta_new

        high_delta_new = num - highest
        if high_delta_new > 0:
            second_highest = highest
            highest = num
        elif high_delta_new <= high_delta:
            second_highest = num
            high_delta = high_delta_new

    return (second_lowest, second_highest)

Now if this does not to need to be speed optimized, simple way would be just take a set of the numbers, sort them, and take the second element from each end:现在,如果这不需要进行速度优化,简单的方法就是取一组数字,对它们进行排序,然后从每一端取第二个元素:

vals = [1,1,3,2,2]
filtered_vals = sorted(set(vals))

and then接着

# Second lowest
In [37]: filtered_vals[1]
Out[37]: 2

# Second highest
In [36]: filtered_vals[-2]
Out[36]: 2

add some Exception and special case handling if needed.如果需要,添加一些异常和特殊情况处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM