2014-09-15 3 views
1

Я пытаюсь понять, почемуИспользование цикла для .setdefault на Dict Создает вложенную Dict

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') 

создает {'a': {'b': {'c': {}}}}

в то время как

root = {} 

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

создает {'a': {}, 'b': {}, 'c': {}}

Что такое вводя в назначенное значение dict на каждой итерации цикла?

+1

Ваша вторая часть кода не дает результата, который вы требуете, если я скопирую его в мой интерпретатор python, я получаю пустой запрос. Что вы хотите, чтобы ваш конечный результат искал, можете ли вы опубликовать это? – dtheodor

+0

@dtheodor спасибо, человек. наклеил неправильный код. обновлено. – MikeiLL

ответ

2

root.setdefault(character, {}) возвращает root[character] если character является ключевым в root или возвращает пустую Dict {}. Это то же самое, что и root.get(character, {}), за исключением того, что он также назначает root[character] = {}, если character еще не является ключом в root.


root = root.setdefault(character, {}) 

переназначение root к новому Словарю, если character уже не является ключевым в оригинальной root.

In [4]: root = dict() 

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

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

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

В отличии от этого, используя 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': {}} 
+0

Вы правы. Я обновил второй набор кода, что я имел в виду. я думаю, что ответ, который я ищу, имеет какое-то отношение к 'state', так что каждый раз через цикл мы получаем« но ждите, есть больше »и добавляем к возвращенному результату. поэтому, когда мы переходим к '.setdefault ('b', {})', который фактически присваивается '{}' в том, что назначено 'root' в пространстве 'a' и снова на одном уровне глубже с ' с». это слово, которое я ищу? – MikeiLL

+1

Да, это связано с «состоянием« root », хотя я думаю, что большинство из них просто скажут« значение «root». Вы можете пройти через код с помощью [онлайн-визуализатора] (http://bit.ly/1m87lf5). Затем измените его, чтобы увидеть, что делает 'root = root.setdefault (...)'. – unutbu

1

Для кого-то, кто является столь же медленно, как и я. Ответ на вопрос: «Почему функция (выше) производит {'a': {'b': {'c': {}, 'd': {}}}}, а не {'a': {}, 'b': {}, 'c': {}}?» is:

Поскольку мы зацикливаемся на функции и переназначая результат для каждого пользователя root, это похоже на рекламные ролики на телевидении, где они продолжают говорить: «Но подождите! есть больше!". Поэтому, когда .setdefault вызывается на 'a', до того, как он возвращается, это результат, {'a': {}} удерживается {внутри цикла}, пока он запускается на 'b', что дает {'b': {}}, в пределах {'a': {}} и удерживается в стороне и {'a': {}} выполняется, то все возвращается из цикла и применяется к дереву. Обратите внимание, что каждый раз, что фактически возвращается .setdefault, является значением по умолчанию, которое в этом случае равно {}. Вот иллюстрация процесса Python Visualizer.

+0

полезно! благодаря – davidlatwe

Смежные вопросы