python dict setdefault,困惑


问题内容

我一直在寻找一种算法,但无法弄清楚为什么dict中d有值而curr没有值。我认为似乎并没有采取任何行动来裁决d

>>> def what(*words):
...     d = {}
...     print d
...     for word in words:
...     print 'word: ' + word
...         curr = d
...         for letter in word:
...             curr = curr.setdefault(letter, {})
...         curr = curr.setdefault('.', '.')
...     print d
...     print '?'
...     print curr
...     return 1
... 
>>> what('foo') 
{}
word: foo
{'f': {'o': {'o': {'.': '.'}}}}
?
.
1

问题答案:

阅读文档dict.setdefault:就像,get但是如果没有密钥,那么它也会被设置:

>>> my_dict = {}
>>> my_dict.setdefault('some key', 'a value')
'a value'
>>> my_dict
{'some key': 'a value'}
>>> my_dict.get('some key2', 'a value2')
'a value2'
>>> my_dict
{'some key': 'a value'}

修改一下您的示例:

>>> def what(*words):
...     d = dict()
...     for word in words:
...             curr = d
...             for letter in word:
...                     curr = curr.setdefault(letter, {})
...             curr = curr.setdefault('.', '.')
...             print 'curr is now: %r while d is %r' % (curr, d)
... 
>>> what('foo')
curr is now: '.' while d is {'f': {'o': {'o': {'.': '.'}}}}

如您所见,curr更改是因为setdefault有时(在您的示例中始终为)调用时创建一个newdict并将其设置为value
curr,而d始终引用原始dict。正如你可以看到它 在循环后修改,因为它的价值是{'f': {'o': {'o': {'.': '.'}}}}它是完全不同的{}

可能是由于curr = curr.setdefault(letter, {}) 始终 创建一个 newempty
dict,然后将其分配给您而造成的困惑curr(因此,对于每个字母,您都向原始字母添加一个嵌套级别,dict而不是覆盖值)。

看到这个:

>>> my_dict = {}
>>> curr = my_dict
>>> for letter in 'foo':
...     print 'my_dict is now %r. curr is now %r' % (my_dict, curr)
...     curr = curr.setdefault(letter, {})
... 
my_dict is now {}. curr is now {}
my_dict is now {'f': {}}. curr is now {}
my_dict is now {'f': {'o': {}}}. curr is now {}
>>> my_dict
{'f': {'o': {'o': {}}}}

如您所见,每个级别my_dict都有一个新的嵌套级别。

也许吧,但我只是在猜测,您想获得类似的东西'foo' -> {'f': {}, 'o': {}},在这种情况下,您应该这样做:

>>> my_dict = {}
>>> for letter in 'foo':
...     my_dict.setdefault(letter, {})
... 
>>> my_dict
{'o': {}, 'f': {}}