简体   繁体   English

在Dict上使用循环来设置.setdefault创建嵌套字典

[英]Using a loop to .setdefault on Dict Creates Nested Dict

I'm trying to understand why 我想知道为什么

tree = {}

def add_to_tree(root, value_string):
    """Given a string of characters `value_string`, create or update a
    series of dictionaries where the value at each level is a dictionary of
    the characters that have been seen following the current character.
    """
    for character in value_string:
        root = root.setdefault(character, {})

add_to_tree(tree, 'abc')

creates {'a': {'b': {'c': {}}}} 创建{'a': {'b': {'c': {}}}}

while

root = {}

root.setdefault('a', {})
root.setdefault('b', {})
root.setdefault('c', {})

creates {'a': {}, 'b': {}, 'c': {}} 创建{'a': {}, 'b': {}, 'c': {}}

What is putting us into the assigned dict value on each iteration of the loop? 是什么让我们在循环的每次迭代中进入指定的dict值?

root.setdefault(character, {}) returns root[character] if character is a key in root or it returns the empty dict {} . root.setdefault(character, {})返回root[character]如果characterroot的键,或者返回空dict {} It is the same as root.get(character, {}) except that it also assigns root[character] = {} if character is not already a key in root . 它与root.get(character, {})相同,只是如果character不是root的键,它也会指定root[character] = {}


root = root.setdefault(character, {})

reassigns root to a new dict if character is not already a key in the original root . 重新分配root到一个新的字典,如果character是不是已经在原来的一个重要root

In [4]: root = dict()

In [5]: newroot = root.setdefault('a', {})

In [6]: root
Out[6]: {'a': {}}

In [7]: newroot
Out[7]: {}

In contrast, using root.setdefault('a', {}) without reassigning its return value to root works: 相反,使用root.setdefault('a', {})而不将其返回值重新分配给root工作:

tree = {}

def add_to_tree(root, value_string):
    """Given a string of characters `value_string`, create or update a
    series of dictionaries where the value at each level is a dictionary of
    the characters that have been seen following the current character.
    """
    for character in value_string:
        root.setdefault(character, {})

add_to_tree(tree, 'abc')
print(tree)
# {'a': {}, 'c': {}, 'b': {}}

For anyone else who is as slow as me. 对于任何和我一样慢的人。 The answer to, "Why does the (above) function produce {'a': {'b': {'c': {}, 'd': {}}}} and not {'a': {}, 'b': {}, 'c': {}} ?" 答案为“为什么(上面)函数产生{'a': {'b': {'c': {}, 'd': {}}}}而不是{'a': {}, 'b': {}, 'c': {}} ?“ is: 是:

Because we're looping within a function and reassigning the the result to root each time, it's kind of like in the TV infomercials where they keep saying, “but wait! 因为我们在一个函数中循环并且每次都将结果重新分配给root,这有点像在他们一直说的电视广告中,“但是等等! there's more!”. 还有更多!”。 So when .setdefault gets called on 'a', before that gets returned, it's result, {'a': {}} is held {inside the loop} while it's run on 'b', which yields {'b': {}} , within {'a': {}} and that is held to the side and {'a': {}} is run, then the whole thing is returned from the loop and applied to tree. 所以当.setdefault在'a'上被调用时,在返回之前,结果是{'a': {}}被保持在{循环内},而它在'b'上运行,产生{'b': {}} ,在{'a': {}} ,并且保持在侧面并运行{'a': {}} ,然后整个事物从循环返回并应用于树。 Note that each time, what is actually returned by .setdefault IS the default, which in this case is {} . 请注意,每次,.setdefault实际返回的内容都是默认值,在本例中为{} Here is a Python Visualizer illustration of the process. 这是一个Python Visualizer插图的过程。

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

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