打印多维字典,重复键
我是新来的Python和目前使用python 2. 我建了一个多维的字典,看起来像这样:打印多维字典,重复键
targets = {house: {N: {red: {A:1}, garden: {N: 6}}}
{great: {A: {very: {Adv:12}, so: {Adv: 5}, a: {Det: 3}}}}
etc.
基本上总会有4的嵌套字典,但的条目'第三'字典({red:{},horse:{}等)可以由任意数量的项目组成。因此,字典中的项目数量会有所不同。
现在,我喜欢将字典写入文件,最好写入一个csv文件。输出文件应以制表符分隔的方式显示所有条目,每行以最外键开始。例如:
house N red A 1
house N garden N 6
great A very Adv 12
great A so Adv 5
great A a Det 3
我知道,有很多关于打印多维字典的帖子,但我还没有找到一个(还),其中最外层的关键是在每个迭代中打印。我试图包含为多维词典的其他问题提供的代码片段,但迄今为止效果不佳。
我好不容易才写字典到字典中的格式正常的.txt文件与此for循环:
for target in targets_dict:
results.write(str(target) + str(targets_dict[str(target)]) + '\n')
或使用csvwriter写入到一个CSV文件(我知道也有DictWriter,我只是无法得到它的正常工作):
w = csv.writer(results, delimiter = '\t')
for target in targets_dict.iteritems():
w.writerow(target)
很显然,这是非常基本的和迭代不进入内字典。
尝试已发布到相关问题的修改解决方案(recursively traverse multidimensional dictionary, dimension unknown)始终驻留在'期望的字符缓冲区对象'错误中。
for for k,v in sorted(targets_dict.items(),key=lambda x: x[0]):
if isinstance(v, dict):
results.write(" ") + ("%s %s") % (k, v)
每一个建议或提示都被赞赏,可以帮助我理解所有这些背后的逻辑,以便我能够弄明白。
这是一个简单的解决方案。这个想法只是将字典循环到列表中,然后从该列表中创建tsv文件,但仅仅是因为你知道嵌套深度(4,看起来好)。下面没有针对速度进行优化,也没有检查任何地方的存在,但希望您能明白。
import csv
targets = {'house': {'N': {'red': {'A':1}, 'garden': {'N': 6}}},
'great': {'A': {'very': {'Adv':12}, 'so': {'Adv': 5}, 'a': {'Det': 3}}}}
with open('targets.tsv', 'w', newline='\n') as tsvfile:
writer = csv.writer(tsvfile, delimiter='\t')
for t in targets:
for u in targets[t]:
for v in targets[t][u]:
for w in targets[t][u][v]:
#print [t, u, v, w, targets[t][u][v][w]]
writer.writerow([t, u, v, w, targets[t][u][v][w]])
打印:
['house', 'N', 'red', 'A', 1]
['house', 'N', 'garden', 'N', 6]
['great', 'A', 'very', 'Adv', 12]
['great', 'A', 'so', 'Adv', 5]
['great', 'A', 'a', 'Det', 3]
而且还创建了TSV文件:
house N red A 1
house N garden N 6
great A very Adv 12
great A so Adv 5
great A a Det 3
编辑:根据在OP(评论在最外面的字典中的键唯一更新的代码并应被视为targets
的关键字)。
递归确实是解决问题的方法。您可以定义递归遍历字典的生成器函数,同时构造遇到的项目的路径。当您遇到非字典的项目只是yield
任何已添加到路径和写入到CSV文件:
import csv
targets = {
'house': {'N': {'red': {'A':1}, 'garden': {'N': 6}}},
'great': {'A': {'very': {'Adv':12}, 'so': {'Adv': 5}, 'a': {'Det': 3}}}
}
def get_rows(o, path=None):
if path is None:
path = []
# Base case, add object to path and yield it
if not isinstance(o, dict):
path.append(o)
yield path
path.pop()
return
for k, v in o.items():
path.append(k)
yield from get_rows(v, path)
path.pop()
with open('result.csv', 'w', newline='') as f:
writer = csv.writer(f, delimiter='\t')
for row in get_rows(targets):
writer.writerow(row)
输出:
great A a Det 3
great A so Adv 5
great A very Adv 12
house N red A 1
house N garden N 6
请注意,您得到的输出可能会以不同的顺序因为dict
是无序的。上述解决方案可以与任何深度的嵌套字典一起工作。如果你正在使用Python 2的代码需要进行调整了一下因为Python 2没有yield from
。
这是刚刚巢很简单的在所有类型的字典循环:
import csv
targets = {'house': {'N': {'red': {'A':1}, 'garden': {'N': 6}}}, 'great': {'A': {'very': {'Adv':12}, 'so': {'Adv': 5}, 'a': {'Det': 3}}}}
with open('file.csv', 'wb') as csvfile:
csvwriter = csv.writer(csvfile, delimiter='\t')
for k,v in targets.iteritems():
for k2,v2 in v.iteritems():
for k3,v3 in v2.iteritems():
for k4,v4 in v3.iteritems():
csvwriter.writerow([str(k), str(k2), str(k3), str(k4), str(v4)])
#print(str(k) + "\t" + str(k2) + "\t" + str(k3) + "\t" + str(k4) + "\t" + str(v4))
输出正是你想要的。
非常感谢你的帮助,代码不正是我在找什么。我非常感谢你的贡献,它帮助了很多! –
回复。变量'targets':这是一个列表的列表,还是最外面的字典中唯一的关键字? – Eugene
都在最外面的字典中的键唯一 –