Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何将嵌套字典打印为具有可变行的复杂表?_Python_Python 2.7_Csv_Dictionary_String Formatting - Fatal编程技术网

Python:如何将嵌套字典打印为具有可变行的复杂表?

Python:如何将嵌套字典打印为具有可变行的复杂表?,python,python-2.7,csv,dictionary,string-formatting,Python,Python 2.7,Csv,Dictionary,String Formatting,假设我有这个嵌套字典: d = {'Ben': {'wo_mana': ['Strength = 1.10', 'Speed = 1.50'], 'wi_mana': ['Int = 1.20'], 'Skill': 'true', 'Magic': 'false'}, 'Tom': {'wi_mana': ['Int = 1.40'], 'wo_mana': ['Agility = 1.60'], 'Skill': 'true', 'Magic': 'true'}} 键和值不是我自

假设我有这个嵌套字典:

d = {'Ben': {'wo_mana': ['Strength = 1.10', 'Speed = 1.50'], 'wi_mana': ['Int = 1.20'], 'Skill': 'true', 'Magic': 'false'},
     'Tom': {'wi_mana': ['Int = 1.40'], 'wo_mana': ['Agility = 1.60'], 'Skill': 'true', 'Magic': 'true'}}
键和值不是我自己定义的,它们实际上是从文件中提取的数据

Skill
Magic
的值的数量是固定的,即1

但是,
wo_mana
wi_mana
的值数量是不固定的,可以是1、2、3、4等

在上面的示例中,
wo_mana
有两个值表示
Ben

我的目标是将其打印到一个表中(用一个选项卡分隔),在Excel中打开时,它如下所示:

Name Skill Magic wo_mana          wi_mana
Ben  true  false Strength = 1.10  Int = 1.20
                 Speed = 1.50
Tom  true  true  Agility = 1.60   Int = 1.40
请注意,对于每个人,
wo_mana
wi_mana
列可以有多行

我已尝试使用
csv
模块,我的代码:

import csv, itertools

header = ['Name', 'Skill', 'Magic', 'wo_mana', 'wi_mana']

with open('output.csv', 'w') as f:
    w = csv.DictWriter(f, header)
    w.writeheader()
    for key, val in sorted(d.items()):
        row = {'Name': key}
        row.update(val)
        w.writerow(row)
我的输出:

Name,Skill,Magic,wo_mana,wi_mana
Ben,true,false,"['Strength = 1.10', 'Speed = 1.50']",['Int = 1.20']
Tom,true,true,['Agility = 1.60'],['Int = 1.40']
因此,似乎不适合使用
csv

所以也许我必须使用
字符串格式
?有人知道如何像那样打印表格吗?任何帮助都将不胜感激

给你(编辑):

这管用!让我知道

编辑: 根据问题:

但是,wo_mana和wi_mana的值的数量是不固定的,可以是1、2、3、4等

所以我假设不会有键错误。 根据评论中的修改声明,以下是解决方案:

它没有在各种条件下进行适当测试,根据我从评论中了解到的情况,它工作正常,如果有任何问题,请告诉我:

import csv, itertools
d = {'Ben': {'Skill': 'true', 'Magic': 'false'},
     'Tom': {'wo_mana': ['Strength = 1.10'], 'wi_mana': ['Int = 1.20', 'O_o'], 'mana': ['Int = 1.20', 'dsadas', 'whatever', '-_-'], 'Skill': 'true', 'Magic': 'true'}}


header = ['Name', 'Skill', 'Magic', 'wo_mana', 'wi_mana', 'mana']

with open('output.csv', 'w') as f:
    w = csv.DictWriter(f, header)
    w.writeheader()
    for key, val in sorted(d.items()):
        row = {'Name': key}
        # print val
        row.update(val)
        dictionary_containing_list = {key: val[key] for key in val if type(val[key])==list}
        if dictionary_containing_list:
            max_length = len(max(dictionary_containing_list.iteritems(), key=lambda x: len(x[1]))[1])
            dict_list = []
            for i in range(max_length):
                dict_ = {}
                for key, val_list in dictionary_containing_list.iteritems():
                    try:
                        dict_[key] = val_list[i]
                    except IndexError:
                        pass
                dict_list.append(dict_)
                row.update(dict_list[0])
            print dict_list
        w.writerow(row)
        if dictionary_containing_list:
            [w.writerow(dict_) for dict_ in dict_list[1:]]

该解决方案是高度通用的,您可以添加任意数量的
mana
s/列,并且可以正常工作。请记住将确切的列名附加到
标题
列表中

对于wo_mana和wi_mana列,您希望以什么格式打印表格?@wolframalpha用制表符或逗号分隔的表格,包括
Name
Skill
Magic
以及
wo_mana
wi_mana
,他们必须在同一个地方table@wolframalpha我已经在帖子的开头说明了我希望我的桌子看起来是什么样子。是的,它可以工作!非常感谢你!如果我遇到任何问题,我会告诉你。嗨,我使用我的实际文件测试了你的代码,在执行这两行代码时,我有一个
KeyError
wo_mana=[val中的项目['wo_mana']]
wi_mana=[val中的项目['wi_mana']]
,只有当
wo\u mana
wi\u mana
存在时,如何执行此行?因为它们不存在于某些
名称中
好吧,我在val.keys()中添加了这些行
If wo_mana/wi_mana():
来检查这些键是否存在,现在我有另一个问题,如果存在另一个
键,我应该做什么更改,例如,
mana
,它与
wo_mana
wi_mana
相同,它可以有多行SSO,如果我再添加一个
mana
,我将有9个不同的案例,对吗?1)
wo\u mana
wi\u mana
mana
2)
wo\u mana
wi\u mana
等。例外情况并不是解决列表长度不一致问题的唯一方法,如果您也可以通过将列表的长度显式存储在不同的变量中来实现这一点,并获得最小长度并在所有列表上迭代,然后是第二个最小长度并在n-1个列表上迭代,就像我在第一种情况下所做的那样。。。为了使程序具有通用性,我使用了上述技术,因此您可以添加任意数量的长度可变的表,而无需担心重写!
import csv, itertools
d = {'Ben': {'Skill': 'true', 'Magic': 'false'},
     'Tom': {'wo_mana': ['Strength = 1.10'], 'wi_mana': ['Int = 1.20', 'O_o'], 'mana': ['Int = 1.20', 'dsadas', 'whatever', '-_-'], 'Skill': 'true', 'Magic': 'true'}}


header = ['Name', 'Skill', 'Magic', 'wo_mana', 'wi_mana', 'mana']

with open('output.csv', 'w') as f:
    w = csv.DictWriter(f, header)
    w.writeheader()
    for key, val in sorted(d.items()):
        row = {'Name': key}
        # print val
        row.update(val)
        dictionary_containing_list = {key: val[key] for key in val if type(val[key])==list}
        if dictionary_containing_list:
            max_length = len(max(dictionary_containing_list.iteritems(), key=lambda x: len(x[1]))[1])
            dict_list = []
            for i in range(max_length):
                dict_ = {}
                for key, val_list in dictionary_containing_list.iteritems():
                    try:
                        dict_[key] = val_list[i]
                    except IndexError:
                        pass
                dict_list.append(dict_)
                row.update(dict_list[0])
            print dict_list
        w.writerow(row)
        if dictionary_containing_list:
            [w.writerow(dict_) for dict_ in dict_list[1:]]