8

Python で各キーの個別の値をカウントする際に問題があります。

私は好きな辞書を持っています

[{"abc":"movies"}, {"abc": "sports"}, {"abc": "music"}, {"xyz": "music"}, {"pqr":"music"}, {"pqr":"movies"},{"pqr":"sports"}, {"pqr":"news"}, {"pqr":"sports"}]

各キーごとに個別の値の数を個別に出力する必要があります。

つまり、印刷したいということです

abc 3
xyz 1
pqr 4

助けてください。

ありがとうございました

4

6 に答える 6

13

回答してから 6 年以上が経過した後、誰かが私が質問を読み違えていたと指摘しました。私の元の回答(以下)は入力シーケンスの一意のキーをカウントしますが、実際には別のカウント固有の問題があります。キーごとに値をカウントしたい。

キーごとに一意の値を正確にカウントするには、最初にそれらの値をセットに収集する必要があります。

values_per_key = {}
for d in iterable_of_dicts:
    for k, v in d.items():
        values_per_key.setdefault(k, set()).add(v)
counts = {k: len(v) for k, v in values_per_key.items()}

これは、入力に対して次を生成します。

>>> values_per_key = {}
>>> for d in iterable_of_dicts:
...     for k, v in d.items():
...         values_per_key.setdefault(k, set()).add(v)
...
>>> counts = {k: len(v) for k, v in values_per_key.items()}
>>> counts
{'abc': 3, 'xyz': 1, 'pqr': 4}

Counter()このクラスが提供する追加機能を利用したい場合は、そのオブジェクトをインスタンスにラップすることができます。以下を参照してください。

>>> from collections import Counter
>>> Counter(counts)
Counter({'pqr': 4, 'abc': 3, 'xyz': 1})

欠点は、入力 iterable が非常に大きい場合、上記のアプローチでは大量のメモリが必要になる可能性があることです。正確なカウントが必要ない場合、たとえば桁数で十分な場合は、ハイパーログログ構造や、ストリームのカウントを「スケッチ」する他のアルゴリズムなど、他のアプローチがあります。

このアプローチでは、サードパーティのライブラリをインストールする必要があります。例として、datasketchプロジェクトはHyperLogLogMinHashの両方を提供しています。HLL の例を次に示します (HyperLogLogPlusPlusクラスを使用します。これは、HLL アプローチに対する最近の改良です)。

from collections import defaultdict
from datasketch import HyperLogLogPlusPlus

counts = defaultdict(HyperLogLogPlusPlus)

for d in iterable_of_dicts:
    for k, v in d.items():
        counts[k].update(v.encode('utf8'))

分散セットアップでは、Redis を使用して HLL カウントを管理できます。


私の元の答え

collections.Counter()インスタンスをいくつかのチェーンと一緒に使用します。

from collections import Counter
from itertools import chain

counts = Counter(chain.from_iterable(e.keys() for e in d))

これにより、入力リストに複数のキーを持つ辞書が正しくカウントされます。

デモ:

>>> from collections import Counter
>>> from itertools import chain
>>> d = [{"abc":"movies"}, {"abc": "sports"}, {"abc": "music"}, {"xyz": "music"}, {"pqr":"music"}, {"pqr":"movies"},{"pqr":"sports"}, {"pqr":"news"}, {"pqr":"sports"}]
>>> Counter(chain.from_iterable(e.keys() for e in d))
Counter({'pqr': 5, 'abc': 3, 'xyz': 1})

または入力辞書に複数のキーがある場合:

>>> d = [{"abc":"movies", 'xyz': 'music', 'pqr': 'music'}, {"abc": "sports", 'pqr': 'movies'}, {"abc": "music", 'pqr': 'sports'}, {"pqr":"news"}, {"pqr":"sports"}]
>>> Counter(chain.from_iterable(e.keys() for e in d))
Counter({'pqr': 5, 'abc': 3, 'xyz': 1})

Aには、要素とそのカウントを逆順でリストするメソッドCounter()など、追加の便利な機能があります。.most_common()

for key, count in counts.most_common():
    print '{}: {}'.format(key, count)

# prints
# 5: pqr
# 3: abc
# 1: xyz
于 2013-05-06T20:13:01.630 に答える
5

カウンターを使用する必要はありません。この方法で達成できます:

# input dictionary
d=[{"abc":"movies"}, {"abc": "sports"}, {"abc": "music"}, {"xyz": "music"}, {"pqr":"music"}, {"pqr":"movies"},{"pqr":"sports"}, {"pqr":"news"}, {"pqr":"sports"}]

# fetch keys
b=[j[0] for i in d for j in i.items()]

# print output
for k in list(set(b)):
    print "{0}: {1}".format(k, b.count(k))
于 2013-05-06T21:41:32.467 に答える
3

あなたが説明しているもの - 各キーに複数の値を持つリスト - は、次のようなものでよりよく視覚化されます:

{'abc': ['movies', 'sports', 'music'],
 'xyz': ['music'],
 'pqr': ['music', 'movies', 'sports', 'news']
}

その場合、挿入するためにもう少し作業を行う必要があります。

  1. すでに存在するかどうかを確認するための検索キー
    • 存在しない場合は、値を持つ新しいキーを作成します[](空のリスト)
  2. 値の取得 (キーに関連付けられたリスト)
  3. if value inチェックされている値がリストに存在するかどうかを確認するために使用します
  4. 新しい値が含まれていない場合は.append()

これにより、保存されている要素の総数を簡単にカウントすることもできます。

# Pseudo-code
for myKey in myDict.keys():
    print "{0}: {1}".format(myKey, len(myDict[myKey])
于 2013-05-06T20:13:54.020 に答える
2
>>> d = [{"abc":"movies"}, {"abc": "sports"}, {"abc": "music"}, {"xyz": "music"},
... {"pqr":"music"}, {"pqr":"movies"},{"pqr":"sports"}, {"pqr":"news"}, 
... {"pqr":"sports"}]
>>> from collections import Counter
>>> counts = Counter(key for dic in d for key in dic.keys())
>>> counts
Counter({'pqr': 5, 'abc': 3, 'xyz': 1})
>>> for key in counts:
...     print (key, counts[key])
...
xyz 1
abc 3
pqr 5
于 2013-05-06T20:12:13.537 に答える
1

collections.Counter を使用します。1 つの項目の辞書のリストがあるとします...

from collections import Counter
listOfDictionaries = [{'abc':'movies'}, {'abc':'sports'}, {'abc':'music'},
    {'xyz':'music'}, {'pqr':'music'}, {'pqr':'movies'},
    {'pqr':'sports'}, {'pqr':'news'}, {'pqr':'sports'}]
Counter(list(dict)[0] for dict in zzz)
于 2013-05-06T20:16:27.223 に答える