当前位置: 首页 > 面试题库 >

将二维列表写入JSON文件

姚鹤龄
2023-03-14
问题内容

我有一个二维列表,如:

data = [[1,2,3], [2,3,4], [4,5,6]]

我想像这样将其写入JSON文件:

{
    'data':[
        [1,2,3],
        [2,3,4],
        [4,5,6]
    ]
}

我得到这个json.dumps(data, indent=4, sort_keys=True)

{
    'data':[
        [
         1,
         2,
         3
        ],
        [
         2,
         3,
         4
        ],
        [
         4,
         5,
         6]
    ]
}

问题答案:

我认为您可以使用我对另一个类似问题的答案来做您想要的事情。当与之搭配使用时json.dumps(),您指出并非由于某种原因json.dump()

在调查此事之后,我发现在链接的答案中被覆盖encode()的派生方法json.JSONEncoder仅在dumps()被调用时才被调用,而在何时dump()被调用时才被调用。

幸运的是,我很快就能够确定在两种情况下都 确实 调用了该iterencode()方法,因此能够通过或多或少地只是将代码移至另一个方法中而解决该问题。
__encode()

紧接在下面的代码是修订版,其中有此更改:

__我对其他问题的回答中的代码的 修改 版本:

from _ctypes import PyObj_FromPtr  # see https://stackoverflow.com/a/15012814/355230
import json
import re


class NoIndent(object):
    """ Value wrapper. """
    def __init__(self, value):
        if not isinstance(value, (list, tuple)):
            raise TypeError('Only lists and tuples can be wrapped')
        self.value = value


class MyEncoder(json.JSONEncoder):
    FORMAT_SPEC = '@@{}@@'  # Unique string pattern of NoIndent object ids.
    regex = re.compile(FORMAT_SPEC.format(r'(\d+)'))  # compile(r'@@(\d+)@@')

    def __init__(self, **kwargs):
        # Keyword arguments to ignore when encoding NoIndent wrapped values.
        ignore = {'cls', 'indent'}

        # Save copy of any keyword argument values needed for use here.
        self._kwargs = {k: v for k, v in kwargs.items() if k not in ignore}
        super(MyEncoder, self).__init__(**kwargs)

    def default(self, obj):
        return (self.FORMAT_SPEC.format(id(obj)) if isinstance(obj, NoIndent)
                    else super(MyEncoder, self).default(obj))

    def iterencode(self, obj, **kwargs):
        format_spec = self.FORMAT_SPEC  # Local var to expedite access.

        # Replace any marked-up NoIndent wrapped values in the JSON repr
        # with the json.dumps() of the corresponding wrapped Python object.
        for encoded in super(MyEncoder, self).iterencode(obj, **kwargs):
            match = self.regex.search(encoded)
            if match:
                id = int(match.group(1))
                no_indent = PyObj_FromPtr(id)
                json_repr = json.dumps(no_indent.value, **self._kwargs)
                # Replace the matched id string with json formatted representation
                # of the corresponding Python object.
                encoded = encoded.replace(
                            '"{}"'.format(format_spec.format(id)), json_repr)

            yield encoded

将其应用于您的问题:

# Example of using it to do get the results you want.

alfa = [('a','b','c'), ('d','e','f'), ('g','h','i')]
data = [(1,2,3), (2,3,4), (4,5,6)]

data_struct = {
    'data': [NoIndent(elem) for elem in data],
    'alfa': [NoIndent(elem) for elem in alfa],
}

print(json.dumps(data_struct, cls=MyEncoder, sort_keys=True, indent=4))

# test custom JSONEncoder with json.dump()
with open('data_struct.json', 'w') as fp:
    json.dump(data_struct, fp, cls=MyEncoder, sort_keys=True, indent=4)
    fp.write('\n')  # Add a newline to very end (optional).

显示的输出(以及data_struct.json文件的结果内容):

{
    "alfa": [
        ["a", "b", "c"],
        ["d", "e", "f"],
        ["g", "h", "i"]
    ],
    "data": [
        [1, 2, 3],
        [2, 3, 4],
        [4, 5, 6]
    ]
}


 类似资料:
  • 问题内容: 我有一长串以下形式的清单- 即列表中的值是不同的类型-浮点数,整数,字符串。如何将其写入csv文件,以便输出的csv文件看起来像 问题答案: Python的内置CSV模块可以轻松处理此问题: 假设您的问题中的清单定义为。您可以通过各种可选参数来调整输出CSV的确切格式,如上面链接的库参考页中所述。 Python 3更新

  • 问题内容: 因为不插入换行符,这是将列表写入文件的最干净的方法吗? 似乎会有一种标准的方法… 问题答案: 你可以使用循环: 在Python 2中,你也可以使用 如果你热衷于单个函数调用,请至少移除方括号[],以便一次打印一个字符串(一个而不是一个)-没有理由占用所有内存具体化整个字符串列表。

  • 我使用supercsv CsvBeanWriter将值写入csv文件。 示例类: 我得到的结果是: 注意

  • 我正在编写一个python程序,可以循环reddit提交,提取数据,并将其作为对象存储在列表中。但是,我在将该列表写入csv文件时遇到困难。文件已创建,但它只是为对象提供某种id标记。我应该如何更改csv代码? 代码 CSV文件

  • 我正在尝试编写我的第一个json文件。但由于某种原因,它实际上不会写入文件。我知道它在做一些事情,因为在运行转储之后,我放入文件中的任何随机文本都会被擦除,但它的位置上没有任何东西。不用说,但加载部分抛出和错误,因为那里什么都没有。这难道不应该将所有json文本添加到文件中吗?

  • 问题内容: 我正在努力将列表字典写入.csv文件。 这是我的字典的样子: 我希望.csv文件看起来像: 首先,我写标题: 到目前为止很好…但是,我的问题是我不知道如何将一个列表分配给相应的列。例如: 将随机填充列。另一个问题是,我必须手动填写键,并且不能将其用于具有4个键的另一本词典。 问题答案: 如果您不关心列的顺序(因为字典是无序的),则可以简单地使用: 结果: 如果您确实关心订单,则需要对键