将Python数据转换为复杂的JSON脚本

2024-04-26 17:35:14 发布

您现在位置:Python中文网/ 问答频道 /正文

很抱歉这个模糊的标题,我需要一些关于Python魔术的帮助,我想不出任何更具描述性的东西。在

我有一个固定的JSON数据结构,我需要将CSV文件转换成这个结构。该结构是固定的,但与列表等深度嵌套。与此类似,但更复杂:

{
    "foo" : bar,
    "baz" : qux,
    "nub" : [
        {
            "bub": "gob",
            "nab": [
                {
                    "nip": "jus",
                    "the": "tip",
                },
                ...
            ],
        },
        ...
    ],
    "cok": "hed"
}

希望你能明白。单字上的列表列表列表上的列表等等。我的csv可能是这样的:

^{pr2}$

抱歉,如果这很难阅读,但基本思想是,如果有一个列出的项目,它将在下一行,并重复值来表示哪些子列表属于什么。在

我不想找任何人来解决这个混乱的问题,也许只是一些关于技术或事情的建议。在

现在我有一个粗略的计划:

我首先将标题转换为包含键的元组列表。对于每一组行(项),我将创建一个模板dict的副本。我有一个函数可以从一组键中设置dict值,除非它找到一个列表。在本例中,我将调用一个有趣的递归函数并将其传递给迭代器,然后继续在该函数中填充dict,并在找到新列表时进行递归调用。在

我也可以做很多硬编码,但有什么乐趣呢?在

这就是我的故事。再说一遍,只是想知道最好的方法是什么。我写这个很快,所以可能有点混乱,请让我知道如果有更多的信息会有帮助。谢谢!在


Tags: 文件csv函数json标题数据结构列表foo
1条回答
网友
1楼 · 发布于 2024-04-26 17:35:14

您的JSON格式不正确。此外,json必须不包含数组才能实现所需的功能。在

def _tocsv(obj, base=''):
    flat_dict = {}
    for k in obj:
        value = obj[k]
        if isinstance(value, dict):
            flat_dict.update(_tocsv(value, base + k + '.'))
        elif isinstance(value, (int, long, str, unicode, float, bool)):
            flat_dict[base + k] = value
        else:
            raise ValueError("Can't serialize value of type "+ type(value).__name__)
    return flat_dict

def tocsv(json_content):
    #assume you imported json
    value = json.loads(json_content)
    if isinstance(value, dict):
        return _tocsv(value)
    else:
        raise ValueError("JSON root object must be a hash")

会让你变平一些东西,比如:

^{pr2}$

比如说:

{"foo": "nestor", "bar": "kirchner", "baz.clorch": 1, "baz.narf": 2, "baz.peep.ooo": "you suck"}

这些钥匙不保存任何特定的顺序。如果要保持顺序,可以用OrderedDict的构造替换{}。在

假设你有一个这样的平面字典数组:

def tocsv_many(json_str):
    #assume you imported json
    value = json.loads(json_content)
    result = []
    if isinstance(value, list):
        for element in value:
            if isinstance(element, dict):
                result.append(_tocsv(element))
            else:
                raise ValueError("root children must be dicts")
    else:
        raise ValueError("The JSON root must be a list")
flat_dicts = tocsv_many(yourJsonInput)

你可以:

  1. 创建一个csvlines = []列表,该列表将保存ur文件的csv行。在
  2. 创建一个keysSet = set(),它将保存可能的键。在
  3. 对于以这种方式得到的每个dict,将.keys()添加到集合中。普通集不能保证键顺序;请改用排序集。最后我们得到了第一个CSV行。在

     for flat_dict in flat_dicts:
         keysSet.extend(flat_dict.keys())
     csvlines.appens(",".join(keysSet))
    
  4. 对于您拥有的每个dict(再次迭代),您将生成如下数组:

     for flat_dict in flat_dicts:
         csvline = ",".join([json.dumps(flat_dict.get(keyInSet, '')) for keyInSet in keysSet])
         csvlines.append(csvline)
    
  5. 喂!你的线路在csvlines

相关问题 更多 >