87

多くの場合、Perl では次のようにします。

$myhash{foo}{bar}{baz} = 1

これを Python に翻訳するにはどうすればよいでしょうか。これまでのところ、私は持っています:

if not 'foo' in myhash:
    myhash['foo'] = {}
if not 'bar' in myhash['foo']:
    myhash['foo']['bar'] = {}
myhash['foo']['bar']['baz'] = 1

より良い方法はありますか?

4

4 に答える 4

120

必要なネスティングの量が固定されている場合は、collections.defaultdict素晴らしいです。

例: 2 つの深さのネスト:

myhash = collections.defaultdict(dict)
myhash[1][2] = 3
myhash[1][3] = 13
myhash[2][4] = 9

別のレベルの入れ子にしたい場合は、次のようにする必要があります。

myhash = collections.defaultdict(lambda : collections.defaultdict(dict))
myhash[1][2][3] = 4
myhash[1][3][3] = 5
myhash[1][2]['test'] = 6

編集: MizardX は、単純な関数で完全な汎用性を得ることができると指摘しています。

import collections
def makehash():
    return collections.defaultdict(makehash)

これで、次のことができます。

myhash = makehash()
myhash[1][2] = 4
myhash[1][3] = 8
myhash[2][5][8] = 17
# etc
于 2009-03-16T21:29:44.153 に答える
108
class AutoVivification(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

テスト:

a = AutoVivification()

a[1][2][3] = 4
a[1][3][3] = 5
a[1][2]['test'] = 6

print a

出力:

{1: {2: {'test': 6, 3: 4}, 3: {3: 5}}}
于 2009-03-16T19:45:34.013 に答える
15

それが口述の口述である必要がある理由はありますか?その特定の構造に説得力のある理由がない場合は、タプルを使用してdictにインデックスを付けることができます。

mydict = {('foo', 'bar', 'baz'):1} # Initializes dict with a key/value pair
mydict[('foo', 'bar', 'baz')]      # Returns 1

mydict[('foo', 'unbar')] = 2       # Sets a value for a new key

タプルキーを使用してdictを初期化する場合は括弧が必要ですが、[]を使用して値を設定/取得する場合は括弧を省略できます。

mydict = {}                        # Initialized the dict
mydict['foo', 'bar', 'baz'] = 1    # Sets a value
mydict['foo', 'bar', 'baz']        # Returns 1
于 2009-03-16T19:56:21.773 に答える
2

直訳は次のようになると思います。

 mydict = {'foo' : { 'bar' : { 'baz':1}}}

呼び出し:

 >>> mydict['foo']['bar']['baz']

あなたに1を与えます。

しかし、それは私には少しひどいように見えます。

(ただし、私はPerlの人ではないので、あなたのperlが何をするかを推測しています)

于 2009-03-16T19:28:00.373 に答える