python字典嵌套字典遍历_遍历/迭代任意深度的嵌套字典(字典表示目录树)

我意识到这是一个老问题,但我只是在寻找一个简单,干净的方式来走嵌套的听写,这是最近的事情,我有限的搜索已经想出。如果你想要的不仅仅是文件名,那么oadams的答案还不够有用,spicavigo的答案看起来很复杂。

最后我只滚动了自己的文件,其行为类似于os.walk处理目录的方式,只是它返回了所有键/值信息。

它返回一个迭代器,对于嵌套dict的“树”中的每个目录,迭代器返回(路径、子dict、值),其中:path是指向dict的路径

sub dict是这个dict中每个sub dict的(key,dict)对的元组

values是这个dict中每个(非dict)项的(key,value)对的元组

def walk(d):

'''

Walk a tree (nested dicts).

For each 'path', or dict, in the tree, returns a 3-tuple containing:

(path, sub-dicts, values)

where:

* path is the path to the dict

* sub-dicts is a tuple of (key,dict) pairs for each sub-dict in this dict

* values is a tuple of (key,value) pairs for each (non-dict) item in this dict

'''

# nested dict keys

nested_keys = tuple(k for k in d.keys() if isinstance(d[k],dict))

# key/value pairs for non-dicts

items = tuple((k,d[k]) for k in d.keys() if k not in nested_keys)

# return path, key/sub-dict pairs, and key/value pairs

yield ('/', [(k,d[k]) for k in nested_keys], items)

# recurse each subdict

for k in nested_keys:

for res in walk(d[k]):

# for each result, stick key in path and pass on

res = ('/%s' % k + res[0], res[1], res[2])

yield res

下面是我用来测试它的代码,尽管里面有一些其他不相关的(但很整洁的)东西:import simplejson as json

from collections import defaultdict

# see https://gist.github.com/2012250

tree = lambda: defaultdict(tree)

def walk(d):

'''

Walk a tree (nested dicts).

For each 'path', or dict, in the tree, returns a 3-tuple containing:

(path, sub-dicts, values)

where:

* path is the path to the dict

* sub-dicts is a tuple of (key,dict) pairs for each sub-dict in this dict

* values is a tuple of (key,value) pairs for each (non-dict) item in this dict

'''

# nested dict keys

nested_keys = tuple(k for k in d.keys() if isinstance(d[k],dict))

# key/value pairs for non-dicts

items = tuple((k,d[k]) for k in d.keys() if k not in nested_keys)

# return path, key/sub-dict pairs, and key/value pairs

yield ('/', [(k,d[k]) for k in nested_keys], items)

# recurse each subdict

for k in nested_keys:

for res in walk(d[k]):

# for each result, stick key in path and pass on

res = ('/%s' % k + res[0], res[1], res[2])

yield res

# use fancy tree to store arbitrary nested paths/values

mem = tree()

root = mem['SomeRootDirectory']

root['foo.txt'] = None

root['bar.txt'] = None

root['Stories']['Horror']['rickscott.txt'] = None

root['Stories']['Horror']['Trash']['notscary.txt'] = None

root['Stories']['Cyberpunk']

root['Poems']['doyoureadme.txt'] = None

# convert to json string

s = json.dumps(mem, indent=2)

#print mem

print s

print

# json.loads converts to nested dicts, need to walk them

for (path, dicts, items) in walk(json.loads(s)):

# this will print every path

print '[%s]' % path

for key,val in items:

# this will print every key,value pair (skips empty paths)

print '%s = %s' % (path+key,val)

print

输出如下:{

"SomeRootDirectory": {

"foo.txt": null,

"Stories": {

"Horror": {

"rickscott.txt": null,

"Trash": {

"notscary.txt": null

}

},

"Cyberpunk": {}

},

"Poems": {

"doyoureadme.txt": null

},

"bar.txt": null

}

}

[/]

[/SomeRootDirectory/]

/SomeRootDirectory/foo.txt = None

/SomeRootDirectory/bar.txt = None

[/SomeRootDirectory/Stories/]

[/SomeRootDirectory/Stories/Horror/]

/SomeRootDirectory/Stories/Horror/rickscott.txt = None

[/SomeRootDirectory/Stories/Horror/Trash/]

/SomeRootDirectory/Stories/Horror/Trash/notscary.txt = None

[/SomeRootDirectory/Stories/Cyberpunk/]

[/SomeRootDirectory/Poems/]

/SomeRootDirectory/Poems/doyoureadme.txt = None

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值