Python 使用重复键打印多维字典
我是python新手,目前正在使用python 2。 我构建了一个多维字典,如下所示:Python 使用重复键打印多维字典,python,dictionary,multidimensional-array,Python,Dictionary,Multidimensional Array,我是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:{}等)的条目可以由任意数量的条目组成。因此,字典中的条目数量会有所不同 现在,我喜欢
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
我知道,有很多关于打印多维字典的帖子,但是我还没有找到在每次迭代过程中打印最外面的键的帖子。我试图包括为多维字典的其他问题提供的代码片段,但到目前为止效果不好
我刚刚通过以下for循环将字典写入字典格式的普通.txt文件:
for target in targets_dict:
results.write(str(target) + str(targets_dict[str(target)]) + '\n')
或者使用csvwriter将其写入csv文件(我知道还有DictWriter,我只是无法使其正常工作):
显然,这是非常基本的,迭代不会进入内部字典
尝试已发布到相关问题()的修改后的解决方案时,始终存在“预期的字符缓冲区对象”错误
for for k,v in sorted(targets_dict.items(),key=lambda x: x[0]):
if isinstance(v, dict):
results.write(" ") + ("%s %s") % (k, v)
非常感谢每一个建议或提示都能帮助我理解这一切背后的逻辑,这样我就能够理解它。这里有一个简单的解决方案。这个想法就是通过dict循环,进入一个列表,然后从该列表中创建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中的注释更新代码(最外层字典中的键是唯一的,应视为
目标的键
).递归确实是问题的解决方案。您可以定义生成器函数,该函数在构造遇到的项的路径时递归遍历字典。当遇到非dict项时,只需生成添加到路径中的任何内容,并将其写入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没有从得到的收益,因此在所有dict上嵌套循环非常简单:
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))
输出您想要的内容。OP声明“输出文件应以制表符分隔的方式显示所有条目”,需要在上面的代码中设置制表符分隔符。@niemmi非常感谢,我在这个项目中使用Python 2,但我在Python 3中尝试过,它提供了所需的输出,这当然是完美的;)Re.变量目标
:这是一个dict列表,还是最外层字典中的所有键都是唯一的?最外层字典中的所有键都是唯一的t dictionary是唯一的非常感谢你的帮助,代码正是我想要的。我真的很感谢你的贡献,它帮助了我很多!哇,感谢你的努力,并对迟来的回复表示抱歉。正如我在上面的评论中所说,targets是最外层的字典,但是我知道你的代码,它帮助我理解t对整体逻辑表示满意。感谢您的回复和选择答案,很多新用户都不这么做,正是像您这样的人恢复了我帮助那些刚起步的人的意愿!再次感谢!
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))