[Python] 再帰的にdictをwalkする関数
2011年8月7日
「自分の子リストを持つdictデータ」を再帰的に評価したかった
例えば以下のようなデータを
adict = {
'name': u'波平',
'children': [
{
'name': u'サザエ',
'children':[{'name':u'タラオ', 'children':[]}],
},
{'name': u'カツオ', 'children':[]},
{'name': u'ワカメ', 'children':[]},
]
}
こんな風に操作したいなと思いました
for child in 関数(adict):
print child['name'] # -> u'波平' から順次表示
walk_dict関数を作ったけど
というわけで、walk_dict(adict, children_key) という関数を作りました
・・・と、要件は満たせたんですが、何か変
for i in walk_dict(child, children_key):
yield i
のところを、generatorを解除するのに1回しか回らんループをしてるのが特に変?
ということで
「○○モジュール使えばいいんじゃないの?お馬鹿なの?」
という、身も蓋もない意見を絶賛募集中です!
という、身も蓋もない意見を絶賛募集中です!
後、ついでにも程がありますが、JavaScriptでも同じような関数を募集中です!!
別解を貰った
@kenji4569 さんから別解を貰ったので、元解答と両方さらしておきます
# 自分
def walk_dict(adict, children_key):
yield adict
for child in adict[children_key]:
for i in walk_dict(child, children_key):
yield i
# @kenji4569 さん
def walk_dict(adict, children_key):
from itertools import chain
return chain([adict], *[walk_dict(child, children_key) for child in adict[children_key]])
JavaScript版
アルゴリズムは一緒です、JSに書き起こしただけ
イテレーターにはなってません
イテレーターにはなってません
function walkObject(obj, childrenKey) {
var sequence = [];
sequence.push(obj);
var children = obj[childrenKey];
for (var i = 0; i < children.length; i++) {
var child = children[i];
sequence = sequence.concat(arguments.callee(child, childrenKey));
}
return sequence;
}