在Python中初始化字典的最佳方法是什么?

在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 

有没有更好的办法?

 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 

testing:

 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}}} 

如果你需要的嵌套量是固定的, collections.defaultdict是美好的。

如嵌套两个深层:

 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 

是否有理由需要成为一个字典的字典? 如果这个特定结构没有强制性的理由,你可以简单地用一个元组索引字典:

 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 

如果使用元组键来初始化字典,则需要使用括号,但使用[]设置/获取值时,可以忽略它们:

 mydict = {} # Initialized the dict mydict['foo', 'bar', 'baz'] = 1 # Sets a value mydict['foo', 'bar', 'baz'] # Returns 1 

我猜字面翻译会是:

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

呼叫:

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

给你1。

但是,这对我来说看起来有点粗俗。

(虽然我不是perl的人,所以我在猜你的Perl是什么)

像这样的嵌套字典(通常)被称为穷人的对象。 是的,这有一个含义,它可能与pythons面向对象性质相关。