2012-07-28 12 views
8

辞書を含む辞書があります。辞書もあります。Python - 辞書内にネストされた値にアクセスする

次のように現在、私は、ID 001は「ビルへ」を取得するために「トランザクションのRef A1」を開梱してい
dictionary = {'ID': 0001, 'Name': 'made up name', 'Transactions': 
       {'Transaction Ref': 'a1', 'Transaction Details': 
        {'Bill To': 'abc', 'Ship To': 'def', 'Product': 'Widget A' 
         ...} ...} ... } 

if dictionary['ID'] == 001: 
    transactions = dictionary['Transactions'] 
     if transactions['Transaction Ref'] == 'a1': 
      transaction_details = transactions['Transaction Details'] 
      bill_to = transaction_details['Bill To'] 

私は助けるが、これは少しされていると考えることができません不格好、特に最後の2行 - 次の線に沿って何かが動作するはずのように私は感じる:

bill_to = transactions['Transaction Details']['Bill To'] 

間に解凍することなく、ネストされた辞書をドリルダウンのための簡単な方法はありますIM変数?

+6

実際に動作するはずの線はありますか? –

答えて

13
bill_to = transactions['Transaction Details']['Bill To'] 

実際に動作します。 transactions['Transaction Details']dictを表す式なので、その中でルックアップを行うことができます。実用的なプログラムでは、入れ子にされたdictsへのOOアプローチを好むでしょう。 collections.namedtupleは、データだけを含むクラスを素早く設定するのに便利です(独自の振る舞いはありません)。

注意点が1つあります:いくつかの設定では、あなたが検索を行う際KeyErrorをキャッチすることがあります、そしてあまりにも動作します。この設定では、辞書検索が失敗した言うのは難しい:

try: 
    bill_to = transactions['Transaction Details']['Bill To'] 
except KeyError: 
    # which of the two lookups failed? 
    # we don't know unless we inspect the exception; 
    # but it's easier to do the lookup and error handling in two steps 
+0

非常に参考になりました - 多くのありがとう! – user1530213

20

あなたが使用することができますこのような何か:

:あなたは、個々のパラメータとして、検索キーを定義したくない場合は

>>> def lookup(dic, key, *keys): 
...  if keys: 
...   return lookup(dic.get(key, {}), *keys) 
...  return dic.get(key) 
... 
>>> d = {'a':{'b':{'c':5}}} 
>>> print lookup(d, 'a', 'b', 'c') 
5 
>>> print lookup(d, 'a', 'c') 
None 

また、あなたはこのようなリストとしてそれらを渡すことができます続い

>>> print lookup(d, *['a', 'b', 'c']) 
5 
>>> print lookup(d, *['a', 'c']) 
None 
+0

この機能の真の動的検索機能を明確にするために編集を追加しました。オンザフライで検索キーのリストを渡す機能は、これを他の技術よりも上手くします。 –

2

は、ネストされた辞書ここ

>>> dbo={'m':{'d':{'v':{'version':1}}}} 
>>> name='m__d__v__version' # it'll refer to 'dbo['m']['d']['v']['version']', '__' is the separator 
>>> version = reduce(dict.get, name.split('__'), dbo) 
>>> print version 
1 
>>> 

アクセス別の方法で、変数 'name' は 'DBO [' M '] [' D '] [' V '] [' バージョン ']を指し'、これははるかに短いときちんとしているようです。

このメソッドはKeyErrorをスローしません。キーが見つからない場合は、「なし」と表示されます。

Ref .: http://code.activestate.com/recipes/475156-using-reduce-to-access-deeply-nested-dictionaries/

+0

name = 'm__foo__v__foo'を試してみると、TypeErrorがスローされます: TypeError:ディスクリプタ 'get'に 'dict'オブジェクトが必要ですが、 'NoneType' – krasnaya

関連する問題