2017-02-14 3 views
0

Я новичок в Python, и я пытаюсь создать простой REST api с флягой. я не понимаю, почему это приводит к ошибке:Вложенные словари в python

boxes = {} 
counter = 1 
for box in ListOfBoxes: 

    boxes['boxes'][counter]['ID']= box.ID 
    boxes['boxes'][counter]['name']= box.name 
    boxes['boxes'][counter]['state']= box.state 
    boxes['boxes'][counter]['directory']= box.directory 
    boxes['boxes'][counter]['provider']= box.provider 
    counter +=1 

return jsonify(boxes) 

Хотя это работает: существо

boxes = {} 
counter = 1 
for box in ListOfBoxes: 

    boxes['boxes'] = {} 
    boxes['boxes'][counter] = [] 
    boxes['boxes'][counter].append({'ID': box.ID, 'name':box.name, 'state': box.state, 'directory': box.directory, 'provider': box.provider}) 
    counter +=1 

return jsonify(boxes) 

Ошибка:

File "./flask/app.py", 
line 16, in get_boxes boxes['boxes'][counter]['ID']= box.ID KeyError: 'boxes' 

Когда прибегая к помощи и stackoverflowing ответы, в основном второй используется фрагмент кода. По крайней мере, это то, что я понимаю из этого.

+0

Возможный дубликат [Что это лучший способ для реализации вложенных словарей] (HTTP : //stackoverflow.com/questions/635483/what-is-the-best-way-to-implement-nested-dictionaries) – TemporalWolf

ответ

0

В первом примере вы пытаетесь получить доступ к неинициализированным значениям.

boxes = {} 
counter = 1 
for box in ListOfBoxes: 

    boxes['boxes'][counter]['ID']= box.ID 

boxes Здесь пустая ДИКТ, но boxes['boxes'] еще не существует, и не какой-либо из других уровней, которые вы пытаетесь получить доступ.

Второй пример иллюстрирует, как инициализировать каждый новый слой в вашей структуре данных, прежде чем пытаться его использовать.

# Create a new Dictionary, assign to a key in Dictionary 'boxes' 
boxes['boxes'] = {} 

# Create a new List, assign to a key in Dictionary we just created 
boxes['boxes'][counter] = [] 

# Now that this List exists, we can use .append() to add to it 
boxes['boxes'][counter].append({'ID': box.ID, 'name':box.name, 'state': box.state, 'directory': box.directory, 'provider': box.provider}) 

Вы получили KeyError потому, что вы пытались получить доступ к словарю ключ, который еще не существовало: boxes['boxes'] никогда не инициализируется иметь значение; поэтому его не существует.

1

Ну, проблема в том, что boxesне содержит ключа 'boxes'. Поскольку вы здесь ** не устанавливаете boxes['boxes'], но вы получаете элемент и выполняете операции над этим элементом.

Способ разрешить его, это, конечно, сразу же вставить элемент с помощью этого ключа в словаре boxes, так:

boxes = {'boxes':[]} 

Тем не менее, это все еще не достаточно, так как вы снова получить boxes['boxes'][counter] для выполнения операций на этом объекте. Итак, вам нужно будет построить словарь.

Однако вы можете переписать код, элегантно используя список постижения и словаря литералов в:

result = [{'ID': box.ID,'name':box.name,'state':box.state, 
      'directory':box.directory,'provider':box.provider} 
      for box in ListOfBoxes] 
boxes = {'boxes':result} 
return jsonify(boxes) 

Если box является объектом и содержит только поля, описанные выше, вы могут использовать только однолинейный:

return jsonify({'boxes':[box.__dict__ for box in ListOfBoxes]})

с __dict__ - словарь объекта (содержащий имя полей, сопоставленных с его значениями). Но это работает только в описанных выше условиях.

1

Простой способ реализации дерева по умолчанию является использование defaultdict:

from collections import defaultdict 

def Tree(): 
    return defaultdict(Tree) 

Тогда:

boxes = Tree() 

boxes['boxes'][5]['provider']= box.provider 
+0

Я получил тот же ответ ... ;-) –

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