什么';在Python中初始化dict的最佳方法是什么?

什么';在Python中初始化dict的最佳方法是什么?,python,autovivification,Python,Autovivification,很多时候,在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 有更好的方法吗?我想直译应该是: mydict = {'foo' : {

很多时候,在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

有更好的方法吗?

我想直译应该是:

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

 >>> mydict['foo']['bar']['baz']
给你1

不过我觉得这有点恶心

(不过,我不是perl专家,所以我在猜测perl的功能)

测试:

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

有没有一个理由,它需要是一个口述的口述?如果该特定结构没有令人信服的理由,您可以简单地使用元组索引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

如果所需的嵌套量是固定的,
collections.defaultdict
非常好

e、 g.嵌套两个深度:

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

不过,这只在初始化时起作用,对吗?@Dana,这与在运行时向mydict添加新值不同。您是否清楚何时可以省略括号?是因为逗号是元组运算符,只有在分组不明确时才需要括号吗?这实际上可能比嵌套字典快,因为只有一个查找而不是三个。是的,用于初始化定义良好的结构,然后将其写入json?一个非常常见的案例/实践…或def makehash():return collections.defaultdict(makehash);myhash=makehash()我对“传统”递归函数没有任何问题,但我发现有些东西是不直观的。古怪的无论如何,谢谢!谢谢你。我需要的是lambda:defaultdict();a['foo']+=1;据我所知,这是因为这里没有指定默认的_工厂。你知道如何克服这个问题吗?在初始化时非常方便,但是使用这个dict似乎没有简单的方法,因为涉及到lambda函数,例如,
print myhash
会得到一堆
之类的东西。是否可以扩展它,使其支持以下行为:a[1][2][3]+=某个值。因此,如果密钥事先不存在,则a[1][2][3]将使用该类型的默认值(some_值)进行初始化?此函数的副作用是,任何获取不存在密钥的尝试都会创建密钥。通常,如果同时设置一个键或子键,您只希望自动创建一个键。是否还有一种方法可以生成赋值变量?因此,给定
var=[1,2,3]
,我可以像
a[var]=1
,它将扩展到
a[1][2][3]=1
var=[1,2]
然后允许
a[var]=1
成为
a[1][2]=1
,如果您使用正常的dicts和tuples:
d={};k=(1,2,3);d[k]=1
然后可以使用
d[1,2,3]
。如果你想使用
d[1][2][3]
(为什么?),你必须修改上面的配方,问另一个问题。记住tat flat比nested好。啊哼,事实上另一个是在5天前被问到的,这两个都是4岁的。。。
myhash = makehash()
myhash[1][2] = 4
myhash[1][3] = 8
myhash[2][5][8] = 17
# etc