54

私はPythonを学んでおり、リストを処理する簡単な方法が利点として提示されています。時々そうですが、これを見てください:

>>> numbers = [20,67,3,2.6,7,74,2.8,90.8,52.8,4,3,2,5,7]
>>> numbers.remove(max(numbers))
>>> max(numbers)
74

リストから 2 番目に大きい数を取得する非常に簡単で迅速な方法。ただし、簡単なリスト処理は、リストを 2 回実行して最大のものを見つけ、次に 2 番目に大きいものを見つけるプログラムを作成するのに役立ちます。また、破壊的でもあります。元のデータを保持したい場合は、データのコピーが 2 つ必要です。必要なもの:

>>> numbers = [20,67,3,2.6,7,74,2.8,90.8,52.8,4,3,2,5,7]
>>> if numbers[0]>numbers[1]):
...    m, m2 = numbers[0], numbers[1]
... else:
...    m, m2 = numbers[1], numbers[0]
...
>>> for x in numbers[2:]:
...    if x>m2:
...       if x>m:
...          m2, m = m, x
...       else:
...          m2 = x
...
>>> m2
74

これはリストを一度だけ実行しますが、前のソリューションのように簡潔で明確ではありません。

だから:このような場合、両方を持つ方法はありますか?最初のバージョンの明瞭さ、しかし 2 番目のシングル スルー?

4

31 に答える 31

74

heapqモジュールを使用できます。

>>> el = [20,67,3,2.6,7,74,2.8,90.8,52.8,4,3,2,5,7]
>>> import heapq
>>> heapq.nlargest(2, el)
[90.8, 74]

そしてそこから…

于 2013-04-25T22:23:22.670 に答える
36

@OscarLopez と私は 2 番目に大きい値が何を意味するかについて意見が異なるため、質問者から提供された最初のアルゴリズムに沿って、私の解釈に従ってコードを投稿します。

def second_largest(numbers):
    count = 0
    m1 = m2 = float('-inf')
    for x in numbers:
        count += 1
        if x > m2:
            if x >= m1:
                m1, m2 = x, m1            
            else:
                m2 = x
    return m2 if count >= 2 else None

(注: Python 2 と 3 ではソート動作が異なるNoneため、ここでは負の無限大が使用されています – Python - Find second least number を参照してください。要素数のチェックにより、実際の答えは未定です。)Nonenumbers

最大値が複数回発生する場合は、2 番目に大きい場合もあります。このアプローチのもう 1 つの点は、要素が 2 つ未満の場合に正しく機能することです。その場合、2 番目に大きいものはありません。

同じテストを実行します:

second_largest([20,67,3,2.6,7,74,2.8,90.8,52.8,4,3,2,5,7])
=> 74
second_largest([1,1,1,1,1,2])
=> 1
second_largest([2,2,2,2,2,1])
=> 2
second_largest([10,7,10])
=> 10
second_largest([1,1,1,1,1,1])
=> 1
second_largest([1])
=> None
second_largest([])
=> None

アップデート

条件を再構築して、パフォーマンスを大幅に改善しました。乱数での私のテストでは、ほぼ 100% です。この理由は、元のバージョンではelif、次の番号がリスト内で最大でない可能性が高いイベントで常に評価されていたためです。言い換えると、リスト内の実質的にすべての数値に対して 2 つの比較が行われましたが、ほとんどの場合は 1 つの比較で十分です。数値が 2 番目に大きい数値よりも大きくない場合は、最大の数値よりも大きくないということです。

于 2013-04-25T23:15:50.393 に答える
25

あなたはいつも使うことができますsorted

>>> sorted(numbers)[-2]
74
于 2013-04-25T22:21:54.183 に答える
20

以下の解決策を試してください。変数O(n)に 2 番目に大きい数値を格納して返します。更新:算術比較が無効になったため、Python 3 で動作するようにコードを調整しました。secondNone

のすべての要素numbersが等しい場合、またはnumbersが空である場合、または単一の要素が含まれている場合、変数secondは最終的に の値になることに注意してくださいNone。これらの場合、「2 番目に大きい」要素はないため、これは正しいことです。

注意:これは「2番目の最大」値を見つけます。「最初の最大値」である値が複数ある場合、それらはすべて同じ最大値として扱われます-私の定義では、次のようなリストで:[10, 7, 10]正しい答えは7.

def second_largest(numbers):
    minimum = float('-inf')
    first, second = minimum, minimum
    for n in numbers:
        if n > first:
            first, second = n, first
        elif first > n > second:
            second = n
    return second if second != minimum else None

ここにいくつかのテストがあります:

second_largest([20, 67, 3, 2.6, 7, 74, 2.8, 90.8, 52.8, 4, 3, 2, 5, 7])
=> 74
second_largest([1, 1, 1, 1, 1, 2])
=> 1
second_largest([2, 2, 2, 2, 2, 1])
=> 1
second_largest([10, 7, 10])
=> 7
second_largest( [1, 3, 10, 16])
=> 10
second_largest([1, 1, 1, 1, 1, 1])
=> None
second_largest([1])
=> None
second_largest([])
=> None
于 2013-04-25T22:51:51.977 に答える
7

なぜシナリオを複雑にするのですか?その非常にシンプルで簡単です

  1. リストをセットに変換 - 重複を削除します
  2. セットを再度リストに変換 - リストを昇順で表示します

ここにコードがあります

mlist = [2, 3, 6, 6, 5]
mlist = list(set(mlist))
print mlist[-2]
于 2016-11-07T07:36:26.407 に答える
1

目的: 入力から 2 番目に大きい数を見つけること。

入力:5 2 3 6 6 5

出力: 5

*n = int(raw_input())
arr = map(int, raw_input().split())
print sorted(list(set(arr)))[-2]*
于 2017-10-24T08:14:54.747 に答える
0

これを試すこともできます:

>>> list=[20, 20, 19, 4, 3, 2, 1,100,200,100]
>>> sorted(set(list), key=int, reverse=True)[1]
100
于 2016-10-24T05:54:14.350 に答える
0

以前の回答のほとんどは正しいですが、ここに別の方法があります!

私たちの戦略は、first_highest と second_highest の 2 つの変数でループを作成することです。数値をループし、current_value が first_highest より大きい場合は、second_highest を first_highest と同じに設定し、second_highest を現在の数値に設定します。現在の数値が second_highest より大きい場合は、second_highest を現在の数値と同じに設定しますここに画像の説明を入力

#!/usr/bin/env python3
import sys
def find_second_highest(numbers):

    min_integer = -sys.maxsize -1
    first_highest= second_highest = min_integer
    for current_number in numbers:
        if current_number == first_highest and min_integer != second_highest:
            first_highest=current_number
        elif current_number > first_highest:
            second_highest = first_highest
            first_highest = current_number
        elif current_number > second_highest:
            second_highest = current_number
    return second_highest

print(find_second_highest([80,90,100]))
print(find_second_highest([80,80]))
print(find_second_highest([2,3,6,6,5]))
于 2018-11-12T06:42:18.037 に答える
0

私の友人である Dhanush Kumar が思いついた最良の解決策は次のとおりです。

    def second_max(loop):
        glo_max = loop[0]
        sec_max = float("-inf")
        for i in loop:
            if i > glo_max:
                sec_max = glo_max
                glo_max=i
            elif sec_max < i < glo_max:
                sec_max = i
        return sec_max
    
    #print(second_max([-1,-3,-4,-5,-7]))
    
    assert second_max([-1,-3,-4,-5,-7])==-3
    assert second_max([5,3,5,1,2]) == 3
    assert second_max([1,2,3,4,5,7]) ==5
    assert second_max([-3,1,2,5,-2,3,4]) == 4
    assert second_max([-3,-2,5,-1,0]) == 0
    assert second_max([0,0,0,1,0]) == 0
于 2020-11-05T13:46:28.667 に答える
0

リストから最大数を削除するのではなく、2 ループを使用して、リストから 2 番目に大きい数を比較して見つけることができます。

def second_largest(list1):
   second_max = list1[0]
   max_nu = max(list1)

   for i in range(len(list1) -1):
       for j in range(1,len(list1)):
          if list1[i] > list1[j] and list1[i] < max_nu :
              second_max = list1[i]
          elif list1[i] < list1[j] and list1[j] < max_nu:
              second_max = list1[j]
   return second_max

l = [2, 4, 5, 6, 8, 7, 21, 20]
print(second_largest(l))
于 2021-11-17T08:09:09.137 に答える
0

簡単な方法:

n=int(input())
arr = set(map(int, input().split()))
arr.remove(max(arr))
print (max(arr))
于 2017-12-18T15:41:12.160 に答える
0
if __name__ == '__main__':
    n = int(input())
    arr = list(map(float, input().split()))
    high = max(arr)
    secondhigh = min(arr)
    for x in arr:
        if x < high and x > secondhigh:
            secondhigh = x
    print(secondhigh)

上記のコードは、ユーザーの要件に従ってリスト内の要素の値を設定しているときのものです。そして、以下のコードは、尋ねられた質問によるものです

#list
numbers = [20, 67, 3 ,2.6, 7, 74, 2.8, 90.8, 52.8, 4, 3, 2, 5, 7]
#find the highest element in the list
high = max(numbers)
#find the lowest element in the list
secondhigh = min(numbers)
for x in numbers:
    '''
    find the second highest element in the list,
    it works even when there are duplicates highest element in the list.
    It runs through the entire list finding the next lowest element
    which is less then highest element but greater than lowest element in
    the list set initially. And assign that value to secondhigh variable, so 
    now this variable will have next lowest element in the list. And by end 
    of loop it will have the second highest element in the list  
    '''
    if (x<high and x>secondhigh):
        secondhigh=x
print(secondhigh)
于 2019-10-02T08:38:46.240 に答える
-1
n=input("Enter a list:")
n.sort()
l=len(n)
n.remove(n[l-1])
l=len(n)
print n[l-1]
于 2015-11-15T02:21:17.493 に答える