2017-02-14 7 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']まだ存在し、またあなたがアクセスしようとしている他のレベルのいずれかを実行しません。

2番目の例では、使用する前にデータ構造内の新しい各レイヤーを初期化する方法を示しています。

# 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

私は同じ答えを得ました... ;-) –