阅读 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
时,它有时(在您的示例中总是)会创建一个新的dict
并将其设置为curr
的值,而d
始终指向原始的dict
。正如您所看到的,循环后d
被修改,因为它的值是{'f': {'o': {'o': {'.': '.'}}}}
,与{}
非常不同。
您的困惑可能是因为 curr = curr.setdefault(letter, {})
始终会创建一个新的和空的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': {}}