繁体   English   中英

python dict setdefault,困惑

[英]python dict setdefault, confused

我正在寻找一种算法,我无法弄清楚为什么dict d有值,而curr没有。 我认为似乎没有任何事情要做到dict 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它有时(在您的示例中始终)创建一个新的dict并将其设置为curr值,而d始终引用原始的dict 你可以看到它在循环之后修改,因为它的值是{'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': {}}

d = dict() - >初始化一个空字典并将其绑定到名称d ; 所以你有一个名字d引用的字典对象( {}

在外部for循环内
curr = d - >将另一个名称curr绑定到同一个对象。 所以,名字( dcurr指的是同一个对象)

在内部for循环内
在第一次迭代期间, letter = 'f'

curr = curr.setdefault(letter, {})

上述声明中有两件事情发生,

A) curr.setdefault(letter, {}) - >根据文档:

“如果key在字典中,则返回其值。如果不是,请插入值为default并返回默认值。默认默认为None。”。

因为,字母'f'不在初始字典对象中,它将初始对象变为{'f':{}}并返回值{} ,它不是初始字典对象,而是创建的新字典对象因为setdefault语句。 此时currd引用了初始字典对象,后者已经变为{'f':{}}

B)将名称curr重新分配给上面提到的返回值。 现在,名称currd引用不同的对象。 d引用对象{'f':{}} ,而curr引用空字典对象,实际上是d['f'] 这就是为什么嵌套发生在原始字典对象中,因为我们经历了循环。

setdefault(key[, default)

来自文档

如果key在字典中,则返回其值。 如果没有,插入key ,值为default和返回default default默认为None

用法示例

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> d.setdefault('a') # returns the corresponding value for key 'a'
1
>>> d.setdefault('a', 10) # returns the corresponding value for key 'a'
1
>>> d.setdefault('b') # returns the corresponding value for key 'b'
2
>>> d.setdefault('c', 100) # returns the corresponding value for key 'c'
3
>>> type(d.setdefault('z')) # because 'z' is not a key of d, None is returned which is the default value of default 
<class 'NoneType'>
>>> d.setdefault('z', 666) # returns 666 since key 'z' is not in d
666

在你的代码中

我觉得你很困惑,因为curr = curr.setdefault(letter, {})总是会创建一个新的空字典 ,然后将其分配给curr 这意味着您不是覆盖值,而是为words每个元素添加嵌套级别到原始字典。

我还认为,要实现你的代码是什么创造一个字典,在每一个元素words与键{}作为值,所以你可以使用一个使用字典,理解下面的代码实现它:

def what(*words):
    return {word: {} for word in set(words)}

注意:我已经添加了setdefault的解释,因为您的问题特别针对此案例进行了查看,但我也想介绍您的具体问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM