67

単語のリストがあり、各単語がそのリストに表示される回数を調べたいとします。

これを行うための明白な方法は次のとおりです。

words = "apple banana apple strawberry banana lemon"
uniques = set(words.split())
freqs = [(item, words.split().count(item)) for item in uniques]
print(freqs)

しかし、このコードはあまり良くないことがわかりました。プログラムは単語リストを2回実行し、1回目はセットを作成し、2回目は出現回数をカウントするためです。

もちろん、リストを実行してカウントを行う関数を作成することもできますが、それはそれほどPythonicではありません。それで、より効率的でPythonicな方法はありますか?

4

13 に答える 13

146

モジュール内のCounterクラスは、collectionsこの種の問題を解決するために構築されています。

from collections import Counter
words = "apple banana apple strawberry banana lemon"
Counter(words.split())
# Counter({'apple': 2, 'banana': 2, 'strawberry': 1, 'lemon': 1})
于 2009-05-21T15:16:59.447 に答える
95

defaultdictを助けてください!

from collections import defaultdict

words = "apple banana apple strawberry banana lemon"

d = defaultdict(int)
for word in words.split():
    d[word] += 1

これは O(n) で実行されます。

于 2009-05-21T15:10:59.647 に答える
12
freqs = {}
for word in words:
    freqs[word] = freqs.get(word, 0) + 1 # fetch and increment OR initialize

これはTriptychのソリューションと同じ結果になると思いますが、コレクションをインポートしません。Selinapのソリューションにも少し似ていますが、より読みやすいimhoです。Thomas Weigel のソリューションとほぼ同じですが、例外を使用していません。

ただし、これはコレクション ライブラリの defaultdict() を使用するよりも遅くなる可能性があります。値がフェッチされ、インクリメントされてから再度割り当てられるためです。単にインクリメントするのではなく。ただし、 += を使用すると、内部的に同じことが行われる場合があります。

于 2009-06-11T20:21:44.627 に答える
11

標準的なアプローチ:

from collections import defaultdict

words = "apple banana apple strawberry banana lemon"
words = words.split()
result = defaultdict(int)
for word in words:
    result[word] += 1

print result

グループ化ワンライナー:

from itertools import groupby

words = "apple banana apple strawberry banana lemon"
words = words.split()

result = dict((key, len(list(group))) for key, group in groupby(sorted(words)))
print result
于 2009-05-21T15:11:47.257 に答える
7

標準の辞書メソッド (リストをループして適切な dict. キーをインクリメントする) を使用したくない場合は、これを試すことができます。

>>> from itertools import groupby
>>> myList = words.split() # ['apple', 'banana', 'apple', 'strawberry', 'banana', 'lemon']
>>> [(k, len(list(g))) for k, g in groupby(sorted(myList))]
[('apple', 2), ('banana', 2), ('lemon', 1), ('strawberry', 1)]

O(n log n) 時間で実行されます。

于 2009-05-21T15:09:57.370 に答える
3

defaultdict を使用しない場合:

words = "apple banana apple strawberry banana lemon"
my_count = {}
for word in words.split():
    try: my_count[word] += 1
    except KeyError: my_count[word] = 1
于 2009-05-21T15:59:30.047 に答える
0

カウントだけでは使えませんか?

words = 'the quick brown fox jumps over the lazy gray dog'
words.count('z')
#output: 1
于 2011-04-07T05:36:08.643 に答える
0

reduce() を使用して、リストを単一の dict に変換します。

from functools import reduce

words = "apple banana apple strawberry banana lemon"
reduce( lambda d, c: d.update([(c, d.get(c,0)+1)]) or d, words.split(), {})

戻り値

{'strawberry': 1, 'lemon': 1, 'apple': 2, 'banana': 2}
于 2016-02-23T18:03:45.900 に答える
0

私はたまたまSparkの演習に取り組んでいました。これが私の解決策です。

tokens = ['quick', 'brown', 'fox', 'jumps', 'lazy', 'dog']

print {n: float(tokens.count(n))/float(len(tokens)) for n in tokens}

**#上記の出力**

{'brown': 0.16666666666666666, 'lazy': 0.16666666666666666, 'jumps': 0.16666666666666666, 'fox': 0.16666666666666666, 'dog': 0.16666666666666666, 'quick': 0.16666666666666666}
于 2015-06-26T06:02:07.303 に答える
0
list = input()  # Providing user input passes multiple tests
text = list.split()

for word in text:
    freq = text.count(word) 
    print(word, freq)
于 2021-10-11T01:11:02.803 に答える
-1

以下の答えはいくつかの余分なサイクルが必要ですが、それは別の方法です

def func(tup):
    return tup[-1]


def print_words(filename):
    f = open("small.txt",'r')
    whole_content = (f.read()).lower()
    print whole_content
    list_content = whole_content.split()
    dict = {}
    for one_word in list_content:
        dict[one_word] = 0
    for one_word in list_content:
        dict[one_word] += 1
    print dict.items()
    print sorted(dict.items(),key=func)
于 2013-02-27T02:17:20.163 に答える