私は次のようにネストされた辞書を持っています。
myTodo= {
'taskid': '10',
'taskstatus': 'in progress',
'Kitchen':
{
'Stove':{
'LED1':
{
'taskid': '11',
'taskstatus':'running'
},
'LED2':
{
'taskid': '12',
'taskstatus':'off',
'LEDSub':
{
'taskid': '13',
'taskstatus':'stable',
'LEDSub2':
{
'taskid': '14',
'taskstatus':'burnt'
}
}
},
'LED3':
{
'taskid': '15',
'taskstatus':'new'
}
},
//other nested layers
}
「値」に到達するためのキーに基づいてルートを返すPythonメソッドがあります。その方法を以下に示します。
def route(myTodo, id):
q = list()
q.append((list(), myTodo))
while q:
this_key_chain, this_v = reverse_linked_q.pop()
# finish search if found the id
if this_v == id:
return this_key_chain
# not found. keep searching
try:
items = this_v.items()
except AttributeError:
continue
for k, v in items:
q.append((this_key_chain + [k], v))
raise KeyError
このメソッドは、キーの観点からルートを返します。したがって、私がそうするとroute(myTodo, "11")
、リストkeyroute = ["Kitchen"、 "Stove"、 "LED1"、 "taskid"]が返されます。
次に、keyrouteリストから「taskid」を削除し、そのリストを次のメソッドに送信します。
def createOutputDic(keyroute, myTodo):
for k in keyroute:
myTodo = myTodo.get(k)
return j
の場合route(myTodo, "11")
、からの出力createOutputDic(keyroute,myTodo)
は
{
'taskid': '11',
'taskstatus':'running'
}
この問題は、として電話をかけるときに発生しroute(myTodo, "12")
ます。私は得ることを期待しています
{ 'taskid': '12',
'taskstatus':'off'
}
しかし、結果は
{
'taskid': '12',
'taskstatus':'off',
'LEDSub':
{
'taskid': '13',
'taskstatus':'stable',
'LEDSub2':
{
'taskid': '14',
'taskstatus':'burnt'
}
}
ただ手に入れたい
{ 'taskid': '12',
'taskstatus':'off'
}
しかし、現在のroute(..)メソッドがそれを実行できない理由がわかりません。辞書は深くネストすることができ、一般的なメソッドが必要です。誰かが私を助けたり、この問題を解決するためのより良い方法を教えてくれますか?どんな助けでも大歓迎です。
ジェネレーターで再帰を使用できます:
def get_data(d, val):
if any(c == val for c in d.values()):
yield {i:d.get(i) for i in ['taskid', 'taskstatus']}
else:
for i in d.values():
if isinstance(i, dict):
yield from get_data(i, val)
myTodo = {'taskid': '10', 'taskstatus': 'in progress', 'Kitchen': {'Stove': {'LED1': {'taskid': '11', 'taskstatus': 'running'}, 'LED2': {'taskid': '12', 'taskstatus': 'off', 'LEDSub': {'taskid': '13', 'taskstatus': 'stable', 'LEDSub2': {'taskid': '14', 'taskstatus': 'burnt'}}}, 'LED3': {'taskid': '15', 'taskstatus': 'new'}}}}
result = list(get_data(myTodo, '12'))
print(result if not result else result[0])
出力:
{'taskid': '12', 'taskstatus': 'off'}
出力をフォーマットするために、目的の出力に含まれているのと同じキーを使用して辞書が作成されます。yield
ステートメントは、メモリ内の他のオブジェクトへのポイントは、オンザフライ「で生成された」というジェネレータオブジェクトを作成します。ジェネレーターベースのソリューションは、を使用するよりも少しクリーンです。return
後者ではfor
、各get_data
呼び出しから返された結果を追加できる2番目のループの外側にリストを作成する必要があるためです。最終的には、呼び出しyield
ごとに使用する方がクリーンget_data
です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加