首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python dict setdefault,混淆

python dict setdefault,混淆
EN

Stack Overflow用户
提问于 2013-03-22 02:45:45
回答 3查看 12.4K关注 0票数 9

我在寻找一种算法,但我不明白为什么dict d中有值,而curr中没有。我认为似乎并没有采取任何行动来判定d

代码语言:javascript
复制
>>> 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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-22 02:49:08

阅读dict.setdefault的文档:它类似于get,但如果键不存在,那么它也是设置的:

代码语言:javascript
复制
>>> 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'}

修改一下你的例子:

代码语言:javascript
复制
>>> 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(因此对于每个字母,您都会向原始<>D23>添加一个嵌套级别,而不是覆盖这些值)。

请看以下内容:

代码语言:javascript
复制
>>> 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': {}}这样的东西,在这种情况下,您应该这样做:

代码语言:javascript
复制
>>> my_dict = {}
>>> for letter in 'foo':
...     my_dict.setdefault(letter, {})
... 
>>> my_dict
{'o': {}, 'f': {}}
票数 12
EN

Stack Overflow用户

发布于 2014-08-12 19:38:29

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

外部for循环中的

curr = d -->将另一个名称curr绑定到同一个对象。因此,名称(dcurr指的是同一个对象)

内部for循环中的

在第一次迭代期间,letter = 'f'

代码语言:javascript
复制
curr = curr.setdefault(letter, {})

在上面的语句中有两件事正在发生,

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

“如果key在字典中,则返回它的值。如果没有,则插入默认的key,并返回default。default默认为None。”。

由于字母'f‘不在初始字典对象中,因此它将初始对象更改为{'f':{}}并返回值{},该值不是初始字典对象,而是由于setdefault语句而创建的新对象。此时,currd都引用了最初的字典对象,该对象后来变成了{'f':{}}

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

票数 3
EN

Stack Overflow用户

发布于 2019-07-12 11:56:48

setdefault(key[, default)

来自the docs

如果key在字典中,则返回它的值。如果不是,则插入值为defaultkey并返回defaultdefault默认为None

用法示例

代码语言:javascript
复制
>>> 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中的每个元素作为关键字,将{}作为值,因此可以使用以下使用字典理解的代码来实现

代码语言:javascript
复制
def what(*words):
    return {word: {} for word in set(words)}

注意:我添加了对setdefault的解释,因为您的问题特别针对此案例进行了查看,但我也想涵盖您的特定问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15555673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档