使用迭代和尾遞歸的混合。在引用未定義的名稱,使間距一致並從第一個結果中除去'k2'之後,我提出了下面的代碼。 (寫入和測試3.4,它應該在任何3.x上運行,並可能在2.7上運行)。需要記住的一個關鍵是,dicts的迭代順序基本上是隨機的,並隨每次運行而變化。遞歸在這裏做的深度優先訪問子字典,而不是廣度優先。對於dict0,兩者是相同的,但是如果dict4嵌套在dict2而不是dict3中,它們不會。
dict0 = {'k0': 0, 'k1': 1, 'dict2':{'k3': 3, 'k4': 4},
'dict3':{'k5': 5, 'dict4':{'k6': 6}}}
def keys(dic, klist=[]):
subdics = []
for key in sorted(dic):
val = dic[key]
if isinstance(val, dict):
subdics.append(val)
else:
klist.append(key)
for subdict in subdics:
keys(subdict, klist)
return klist
result = keys(dict0)
print(result, '\n', result == ['k0','k1','k3','k4','k5','k6'])
def keylines(dic, name='outer_dict', lines=[]):
vals = []
subdics = []
for key in sorted(dic):
val = dic[key]
if isinstance(val, dict):
subdics.append((key,val))
else:
vals.append(key)
vals.extend(pair[0] for pair in subdics)
lines.append('{}_keys = {}'.format(name, vals))
for subdict in subdics:
keylines(subdict[1], subdict[0], lines)
return lines
result = keylines(dict0)
for line in result:
print(line,)
print()
expect = [
"outer_dict_keys = ['k0', 'k1', 'dict2', 'dict3']",
"dict2_keys = ['k3', 'k4']",
"dict3_keys = ['k5', 'dict4']",
"dict4_keys = ['k6']"]
for actual, want in zip(result, expect):
if actual != want:
print(want)
for i, (c1, c2) in enumerate(zip(actual, want)):
if c1 != c2:
print(i, c1, c2)
這太棒了。謝謝Terry! – GoldenPlatinum 2014-10-17 02:25:54