私は2つの辞書を持っていますが、それらは同様の構造です...つまり、ネストされたキー内であっても、同じキー構造を持つ必要があります。また、これらのディクショナリは、ほとんどすべてのタイプのネストされた構造を持つ可能性があります...リスト、ディクテーションなど...これらのディクショナリを走査し、2 つの値を取得して関数から返すことができるようにしたいと考えています。
簡単な例:
dict_a = {'a':1, 'b':2, 'c':{'d':3}}
dict_b = {'a':2, 'b':4, 'c':{'d':6}}
#Note the structure is the same for these dicts
#I want to be able to do something like:
>>get_values( dict_a, dict_b)
[(1,2),(2,4),(3,6)]
1つの辞書をトラバースし、各キー(またはリストに遭遇した場合はインデックス)をリストに追加することで、自分で解決策を思いつきました...一種のキーパスとして:
key_map = []#A list of all key-paths for a dictionary
generate_key_paths(dict_a, [], key_map)
def generate_key_paths(value, key_list,key_map ):
new_list = [item for item in key_list]
if isinstance( value, dict):
#Handle list
for key, val in value.iteritems():
new_list.append( key)
self._generate_key_paths( val, new_list, key_map )
new_list = [item for item in key_list]
elif isinstance( value, list ):
#Handle list
for idx,item in enumerate(value):
new_list.append( idx )
self._generate_key_paths( item, new_list, key_map )
new_list = [item for item in key_list]
else:
#Handle data--reached farthest point you can go
#So just append (key-path, value) to key_map
key_map.append((new_list, value ) )
そして、キーパス、値のタプルのリストを取得したら...パスを取得し、2番目の辞書でそれに到達してその値を取得しようとします...
val_list = []
for item in key_map:
value = get_value( item[0] )
if value is not None:
val_list.append( (item[1], value ) )
def get_value( key_list ):
value = dict_b
for item in key_list:
try:
value = value[item]
except:
value = None
break
return value
これは、ディクショナリが持つことができるすべての構造に対して非常にうまく機能しますが、多くの作業のように思えます。これを達成するためのよりpythonicな方法はありますか?より速く、より効率的な方法はありますか?
編集:リストでも辞書でもない値を探しているので、これらの値に到達すると、値が見つかるまでそれらの中で反復する必要があります。リストの場合は辞書のリストになることが保証されているため、常に何らかのキー:値の関係に従う必要があります。
たとえば、可能な dict は次のようになります。
dict_a = {'a':1, 'b':2, 'c':[{'d':5},{'e':6}]}
dict_b = {'a':2, 'b':4, 'c':[{'d':10},{'e':12}]}
答え:[(1,2), (2,4), (5,10), (6,12)]