10

Python で実装しようとしている機能が可能かどうかを知りたかったのです。

Creatures というグローバル ハッシュがあります。生き物には、哺乳類、両生類、鳥、昆虫と呼ばれるサブハッシュが含まれています。

哺乳類には、クジラやゾウと呼ばれるサブハッシュがあります。両生類には、カエル、幼虫と呼ばれるサブハッシュがあります。鳥には、イーグル、インコと呼ばれるサブハッシュがあります。昆虫には、トンボ、蚊と呼ばれるサブハッシュがあります。

繰り返しますが、イーグルには男性、女性と呼ばれるサブハッシュがあります。

テキストファイルからこれらすべての生き物の頻度を数えています。たとえば、ファイルが次の形式の場合:

Birds   Eagle  Female
Mammals whales Male
Birds   Eagle  Female

I should output Creatures[Birds[Eagle[Female]]] = 2
                Creatures[mammals[Whales[Male]]] = 1  

Pythonで可能ですか?どうすればそれができますか?私はPythonに非常に慣れていないので、助けてください。私は辞書を 1 レベルまで、つまり key-> value だけで十分です。しかし、ここでは、複数のキーと複数の値があります。これをどのように進めるかわかりません。私はpython 2.6を使用しています。よろしくお願いします!

4

3 に答える 3

29

ディクショナリのキーに割り当てられた値自体が別のディクショナリになる場合があります

creatures = dict()
creatures['birds'] = dict()
creatures['birds']['eagle'] = dict()
creatures['birds']['eagle']['female'] = 0
creatures['birds']['eagle']['female'] += 1

ただし、各辞書を明示的に作成する必要があります。Perl とは異なり、割り当てられていないキーの値をそのように処理しようとしても、Python は辞書を自動的に作成しません。

もちろん、次を使用しない限りdefaultdict:

from collections import defaultdict
creatures = defaultdict( lambda: defaultdict(lambda: defaultdict( int )))
creatures['birds']['eagle']['female'] += 1

任意のレベルのネストの場合、この再帰的定義を使用できます

dd = defaultdict( lambda: dd )
creatures = dd
creatures['birds']['eagle']['female'] = 0

この場合、整数値を明示的に初期化する必要があります。そうしないと、 の値creatures['birds']['eagle']['female']が別の と見なされるためdefaultdictです。

>>> creatures = dd
>>> type(creatures['birds']['eagle']['female'])
<class 'collections.defaultdict'>
于 2013-06-17T18:40:59.563 に答える
2

物事を「カウント」する必要があるだけで、データファイルに必要なレベルの「ハッシュ」がすべて含まれていると仮定すると、次のようになります。

import collections

result = collections.defaultdict(int)

with open("beast","rt") as f:
    for line in f:
        hashes = line.split()
        key = '-'.join(hashes)
        result[key] += 1

print result

結果の生成:
defaultdict(<type 'int'>, {'Mammals-whales-Male': 1, 'Birds-Eagle-Female': 2})

ネストされた辞書が必要な場合 -- その結果の後処理はまだ可能です...

于 2013-06-17T18:46:01.347 に答える
1

エレガントではありませんが、機能しています:

result = {}
for line in input_file.split("\n"):
    curdict = result
    values = line.split(" ")
    for item in values[:-1]:
        if item not in curdict:
            curdict[item] = {}
        curdict = curdict[item]
    last_item = values[-1]
    if last_item not in curdict:
        curdict[last_item] = 0
    curdict[last_item] += 1

これはおそらくよりきれいな方法で書くことができますが、少なくともそれは機能し、同じ「エンティティ」に対して異なるネストレベルを持たない限り (たとえば、機能しない場合)、任意のネストレベルを許可しBirds Eagle FemaleますBirds Eagle

于 2013-06-17T18:55:43.350 に答える