如何将存储在字典数据中的JSON数据写入文件?

f = open('data.json', 'wb')
f.write(data)

这会导致错误:

TypeError:必须是字符串或缓冲区,而不是dict


当前回答

使用Python 2+3读写JSON文件;使用unicode

# -*- coding: utf-8 -*-
import json

# Make it work for Python 2+3 and with Unicode
import io
try:
    to_unicode = unicode
except NameError:
    to_unicode = str

# Define data
data = {'a list': [1, 42, 3.141, 1337, 'help', u'€'],
        'a string': 'bla',
        'another dict': {'foo': 'bar',
                         'key': 'value',
                         'the answer': 42}}

# Write JSON file
with io.open('data.json', 'w', encoding='utf8') as outfile:
    str_ = json.dumps(data,
                      indent=4, sort_keys=True,
                      separators=(',', ': '), ensure_ascii=False)
    outfile.write(to_unicode(str_))

# Read JSON file
with open('data.json') as data_file:
    data_loaded = json.load(data_file)

print(data == data_loaded)

json.dump参数说明:

indent:使用4个空格来缩进每个条目,例如,当一个新的dict开始时(否则所有的都将在一行中),sortkeys:对字典的关键字进行排序。如果您想将json文件与diff工具进行比较/将其置于版本控制之下,这非常有用。分隔符:防止Python添加尾随空格

带一个包装

看看我的实用程序包mpu,找到一个超级简单、易于记忆的:

import mpu.io
data = mpu.io.read('example.json')
mpu.io.write('example.json', data)

已创建JSON文件

{
    "a list":[
        1,
        42,
        3.141,
        1337,
        "help",
        "€"
    ],
    "a string":"bla",
    "another dict":{
        "foo":"bar",
        "key":"value",
        "the answer":42
    }
}

常用文件结尾

.json文件

选择

CSV:超简单格式(读写)JSON:适合编写人类可读数据;非常常用(读写)YAML:YAML是JSON的超集,但更易于阅读(读写,JSON和YAML的比较)pickle:Python序列化格式(读写)MessagePack(Python包):更紧凑的表示(读写)HDF5(Python包):适合矩阵(读写)XML:也存在*叹息*(读写)

对于您的应用程序,以下内容可能很重要:

其他编程语言的支持读/写性能紧凑性(文件大小)

另请参阅:数据序列化格式的比较

如果您正在寻找创建配置文件的方法,您可能需要阅读我的Python配置文件短文

其他回答

要获得utf8编码文件,而不是Python 2公认答案中的ascii编码文件,请使用:

import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
  f.write(json.dumps(data, ensure_ascii=False))

Python 3中的代码更简单:

import json
with open('data.txt', 'w') as f:
  json.dump(data, f, ensure_ascii=False)

在Windows上,仍然需要使用encoding='utf-8'参数打开。

要避免在内存中存储数据的编码副本(转储的结果),并在Python 2和3中输出utf8编码字节字符串,请使用:

import json, codecs
with open('data.txt', 'wb') as f:
    json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)

codecs.getwriter调用在Python 3中是冗余的,但在Python 2中是必需的


可读性和尺寸:

ensure_ascii=False的使用提供了更好的可读性和更小的大小:

>>> json.dumps({'price': '€10'})
'{"price": "\\u20ac10"}'
>>> json.dumps({'price': '€10'}, ensure_ascii=False)
'{"price": "€10"}'

>>> len(json.dumps({'абвгд': 1}))
37
>>> len(json.dumps({'абвгд': 1}, ensure_ascii=False).encode('utf8'))
17

通过在dump或dumps的参数中添加标志indent=4,sort_keys=True(如dinos66所建议的),进一步提高可读性。通过这种方式,您将在json文件中获得一个很好的缩进排序结构,代价是文件大小稍大。

json.dump(data, open('data.txt', 'wb'))

如果您试图使用json格式将panda数据帧写入文件,我建议您这样做

destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()

这只是对json.dumps用法的一个额外提示(这不是问题的答案,而是那些必须转储numpy数据类型的人的一个技巧):

如果字典中有NumPy数据类型,json.dumps()需要一个额外的参数,信用转到TypeError:'ndarray'类型的对象不可json序列化,它还将修复TypeError:int64类型的对象不能json序列化等错误:

class NumpyEncoder(json.JSONEncoder):
    """ Special json encoder for np types """
    def default(self, obj):
        if isinstance(obj, (np.int_, np.intc, np.intp, np.int8,
                            np.int16, np.int32, np.int64, np.uint8,
                            np.uint16, np.uint32, np.uint64)):
            return int(obj)
        elif isinstance(obj, (np.float_, np.float16, np.float32,
                              np.float64)):
            return float(obj)
        elif isinstance(obj, (np.ndarray,)):
            return obj.tolist()
        return json.JSONEncoder.default(self, obj)

然后运行:

import json

#print(json.dumps(my_data[:2], indent=4, cls=NumpyEncoder)))
with open(my_dir+'/my_filename.json', 'w') as f:
    json.dumps(my_data, indent=4, cls=NumpyEncoder)))

在np.array()的情况下,您可能还希望返回字符串而不是列表,因为数组被打印为分布在行上的列表,如果您有大或多个数组,则会放大输出。需要注意的是:稍后从转储的字典中访问项以将其恢复为原始数组会更加困难。然而,如果您不介意只使用一个数组字符串,这会使字典更可读。然后交换:

        elif isinstance(obj, (np.ndarray,)):
            return obj.tolist()

具有:

        elif isinstance(obj, (np.ndarray,)):
            return str(obj)

或者只是:

        else:
            return str(obj)

JSON数据可以按如下方式写入文件

hist1 = [{'val_loss': [0.5139984398465246],
'val_acc': [0.8002029867684085],
'loss': [0.593220705309384],
'acc': [0.7687131817929321]},
{'val_loss': [0.46456472964199463],
'val_acc': [0.8173602046780344],
'loss': [0.4932038113037539],
'acc': [0.8063946213802453]}]

写入文件:

with open('text1.json', 'w') as f:
     json.dump(hist1, f)