web-dev-qa-db-ja.com

リスト内の過半数の要素を見つけようとしています

Pythonリストで過半数を見つける関数を書いています。

すべての要素を新しい配列の単一のスロットまたは一意の識別子(おそらく辞書の場合)にマップできるハッシュ関数を記述できれば、それが最善であり、元に戻すことができるはずだと考えています。どうすればいいのかわからない。私のハッシュ関数は明らかに役に立たない、私ができる/すべきことについてのヒント、またはこれが合理的なアプローチでさえあるかどうか?

def find_majority(k):
    def hash_it(q):
        return q

    map_of = [0]*len(k)

    for i in k:
        mapped_to = hash_it(i) #hash function
        map_of[mapped_to]+=1


find_majority([1,2,3,4,3,3,2,4,5,6,1,2,3,4,5,1,2,3,4,6,5])
16
bezzoon

あなたのアプローチは、「ハッシュマップ」と同じ大きさのkの別の配列を使用することだと思います。 kが巨大であるが、一意の要素の数がそれほど多くない場合、多くのスペースを浪費することになります。さらに、過半数を見つけるには、map_ofハッシュマップ/配列をループして最大値を見つける必要があります。

一方、辞書/セット(ハッシュは問題ではなく、基礎となる配列構造は平均的な場合によりコンパクトになる可能性があります)はもう少し適切なようです。言うまでもなく、出現する要素をキーとして、出現する要素を値として、1回の反復で必要なものを見つけることができます。

だから、次のようなもの:

def find_majority(k):
    myMap = {}
    maximum = ( '', 0 ) # (occurring element, occurrences)
    for n in k:
        if n in myMap: myMap[n] += 1
        else: myMap[n] = 1

        # Keep track of maximum on the go
        if myMap[n] > maximum[1]: maximum = (n,myMap[n])

    return maximum

そして、予想通り、私たちは欲しいものを手に入れました。

>>> find_majority([1,2,3,4,3,3,2,4,5,6,1,2,3,4,5,1,2,3,4,6,5])
(3, 5)

もちろん、Countersやその他のクールなモジュールを使用すると、より細かい構文でやりたいことができます。

5
slider

Pythonには、これを行うCounterという組み込みクラスがあります。

>>> from collections import Counter
>>> c = Counter([1,2,3,4,3,3,2,4,5,6,1,2,3,4,5,1,2,3,4,6,5])
>>> c.most_common()
[(3, 5), (2, 4), (4, 4), (1, 3), (5, 3), (6, 2)]
>>> value, count = c.most_common()[0]
>>> print value
3

ドキュメントを参照してください。

http://docs.python.org/2/library/collections.html#collections.Counter

33
FogleBird

このように実現する簡単な方法があります

l = [1,2,3,4,3,3,2,4,5,6,1,2,3,4,5,1,2,3,4,6,5]
print(max(set(l), key = l.count)) # 3
10
Xin Wang