2016-04-26 16 views
4

ある辞書値を取得する私はこれにアクセスするには値2 を取得したいは、キーの一部が文字列で

dict = {"word":{"a":{"b":2}}} 

辞書を取る私が欲しいしかし、私はこのdict["word"]["a"]["b"]

を行うことができます知っている私は、文字列

にキー(["a"]["b]節)の一部を持っており、それには、この

のようなものを参照することができますその

のような0

か何か私はこの構文が間違っているが、それはこのような何かを行うことが可能です知っていますか? Pythonの3.xでは

EDIT: よりよい辞書の例では、それぞれの場合にbの値を取得するにはどのようにこの

dict = { 
"word":{"a":{"b":2}} 
"hello":{"a":{"b":1}} 
"mouse":{"a":{"b":5}} 
} 

ことができますか?キーの["a"]["b"]ビットが変更される可能性がある場合に、ハードコーディングを避けたい場合に使用します。

+2

である場合は、これを使用してのコンテキストは何ですか? – mattsap

+1

これは大文字小文字の問題かもしれません - ネストされた辞書項目をそのような方法でストリング経由で参照することはできませんが、そうしたいと思うことは別の方法で可能です。だから、あなたはそれで何をしたいですか? – Roberto

+0

Pythonは 'eval'機能を持っていますが、これは動作させる可能性がありますが、私は前のコメントに同意します。 – usr2564301

答えて

3

dictを変数名に使用しないでください。これは、組み込み関数をシャドウするためです。


1つの方法は、re moduleです。ここでの主な考え方は、正規表現を利用してキーを見つけることです。キーのリストを取得したら、データを抽出するのは簡単な作業です。

>>> d = {"word":{"a":{"b":2}}} 
>>> s = '["a"]["b"]' 
>>> import re 
>>> keys = re.findall(r'\["(.+?)"\]',s) 
>>> d["word"][keys[0]][keys[1]] 
2 

キーが多い場合は、functoolsパッケージからreduceを使用することができます。長いdictsのために

>>> import functools 
>>> functools.reduce(dict.__getitem__, keys, d['word']) 
2 

(JonClementsがcommentで述べたように)、あなたはlist comprehension

>>> d = { 
... "word":{"a":{"b":2}}, 
... "hello":{"a":{"b":1}}, 
... "mouse":{"a":{"b":5}} 
... } 
>>> [functools.reduce(dict.__getitem__, keys, d[i]) for i in d] 
[2, 5, 1] 

を使用することができますしかし、辞書のキーの順不同の性質のために、リストの出力を点に注意してください期待どおりにならない可能性があります。より良い方法は、最善の方法は、あなたが解析します独自の構文を書くことです

>>> {i:functools.reduce(dict.__getitem__, keys, d[i]) for i in d} 
{'word': 2, 'mouse': 5, 'hello': 1} 
+0

もちろん、キーを抽出したら(どのような構文でも)、次のように変更することができます: 'functools.reduce(dict .__ getitem__、 'ab'、d ['word']) 'これをもっと柔軟にするには...ちょうど良い構文で' 'ab ''を取得する必要があります(おそらく' input'から何かを取り出して 'ast.literal_eval'を実行しています...) –

+0

おそらくキーが複数の文字/非文字列のキーの場合には、文字列の代わりにリスト/タプル(つまり、元の 're.findall'' keys')を保持してください:) –

+0

もちろん、値の順番(重要であると仮定)は、ソースが「OrderedDict」でない限り、驚くかもしれません:) –

2

のように、新しいもの(dictの内包表記を使用して)への完全な辞書を削減することです。キーには表示されないキャラクタを使用する必要があります。一般的な例は.ですが、同様に$,|のように機能します。質問への更新のため

def get(d, key): 
    kp = key.split('.') 
    for k in kp: 
     d = d[k] 
    return d 

d = {'a': {'b': 2}} 
get(d, 'a.b') 
>>> 2 

EDIT:

ですから、それらのそれぞれの場合には、具体的a.bの値のリストを取得できるようにしたいですか?あなたはまだそれほどのような

d = { 
"word":{"a":{"b":2}}, 
"hello":{"a":{"b":1}}, 
"mouse":{"a":{"b":5}}, 
} 

# nesting calls to get just to show it is flexible like that 
[get(get(d, k), 'a.b') for k in d.keys()] 
# if you wanted to generate a dict of {"word": val} it would look like this 
{k:get(get(d, k), 'a.b') for k in d.keys()} 

上記の方法を使用することができそうだとすればそれも動作しますあなたの可変部分が真ん中

d = { 
"x": {"word":{"a":{"b":2}}}, 
"x": {"hello":{"a":{"b":1}}}, 
"x": {"mouse":{"a":{"b":5}}}, 
} 

# using more calls to get just to show it is flexible like that 
[get(get(d, 'x.'+k), 'a.b') for k in get(d, 'x').keys()] 
関連する問題