存储Python字典

我习惯使用CSV文件在Python中输入和输出数据,但这存在明显的挑战。是否有简单的方法将字典(或字典集)存储在JSON或泡菜文件中?

例如:

data = {}
data ['key1'] = "keyinfo"
data ['key2'] = "keyinfo2"

我想知道如何保存这个,然后如何加载它回来。

405853 次浏览

写入文件:

import json
myfile.write(json.dumps(mydict))

从文件中读取:

import json
mydict = json.loads(myfile.read())

myfile是存放字典的文件的文件对象。

最小示例,直接写入文件:

import json
json.dump(data, open(filename, 'wb'))
data = json.load(open(filename))

或安全地打开/关闭:

import json
with open(filename, 'wb') as outfile:
json.dump(data, outfile)
with open(filename) as infile:
data = json.load(infile)

如果你想保存在字符串而不是文件中:

import json
json_str = json.dumps(data)
data = json.loads(json_str)

如果你在序列化,但在其他程序中不需要数据,我强烈推荐shelve模块。可以把它看作一个持久化字典。

myData = shelve.open('/path/to/file')


# Check for values.
keyVar in myData


# Set values
myData[anotherKey] = someValue


# Save the data for future use.
myData.close()

Pickle save:

try:
import cPickle as pickle
except ImportError:  # Python 3.x
import pickle


with open('data.p', 'wb') as fp:
pickle.dump(data, fp, protocol=pickle.HIGHEST_PROTOCOL)

有关protocol参数的附加信息,请参阅pickle模块文档

Pickle load:

with open('data.p', 'rb') as fp:
data = pickle.load(fp)

JSON save:

import json


with open('data.json', 'w') as fp:
json.dump(data, fp)

提供额外的参数,如sort_keysindent,以获得一个漂亮的结果。参数sort_keys将按字母顺序排序键,而缩进将用indent=N空格缩进数据结构。

json.dump(data, fp, sort_keys=True, indent=4)

JSON load:

with open('data.json', 'r') as fp:
data = json.load(fp)

如果你想要picklejson的替代品,你可以使用klepto

>>> init = {'y': 2, 'x': 1, 'z': 3}
>>> import klepto
>>> cache = klepto.archives.file_archive('memo', init, serialized=False)
>>> cache
{'y': 2, 'x': 1, 'z': 3}
>>>
>>> # dump dictionary to the file 'memo.py'
>>> cache.dump()
>>>
>>> # import from 'memo.py'
>>> from memo import memo
>>> print memo
{'y': 2, 'x': 1, 'z': 3}

对于klepto,如果你使用了serialized=True,字典将会作为一个pickle字典而不是明文写入memo.pkl

你可以在这里得到klepto: https://github.com/uqfoundation/klepto

对于pickle来说,dill可能是比pickle本身更好的选择,因为dill可以序列化python中的几乎任何东西。klepto也可以使用dill

你可以在这里得到dill: https://github.com/uqfoundation/dill

前几行中额外的繁冗语句是因为klepto可以被配置为将字典存储到文件、目录上下文或SQL数据库。无论您选择什么作为后端存档,API都是相同的。它为你提供了一个“可存档”的字典,你可以使用loaddump与存档进行交互。

也可以查看加速包ujson:

import ujson


with open('data.json', 'wb') as fp:
ujson.dump(data, fp)

如果保存为JSON文件,最好和最简单的方法是:

import json
with open("file.json", "wb") as f:
f.write(json.dumps(dict).encode("utf-8"))

为了完整起见,我们应该包括ConfigParser和ConfigParser,它们分别是Python 2和3中的标准库的一部分。这个模块读取和写入一个config/ini文件,并且(至少在Python 3中)在很多方面都像一个字典。它还有一个额外的好处,你可以将多个字典存储到config/ini文件的单独部分中,并收回它们。甜蜜的!

Python 2.7。x的例子。

import ConfigParser


config = ConfigParser.ConfigParser()


dict1 = {'key1':'keyinfo', 'key2':'keyinfo2'}
dict2 = {'k1':'hot', 'k2':'cross', 'k3':'buns'}
dict3 = {'x':1, 'y':2, 'z':3}


# Make each dictionary a separate section in the configuration
config.add_section('dict1')
for key in dict1.keys():
config.set('dict1', key, dict1[key])
   

config.add_section('dict2')
for key in dict2.keys():
config.set('dict2', key, dict2[key])


config.add_section('dict3')
for key in dict3.keys():
config.set('dict3', key, dict3[key])


# Save the configuration to a file
f = open('config.ini', 'w')
config.write(f)
f.close()


# Read the configuration from a file
config2 = ConfigParser.ConfigParser()
config2.read('config.ini')


dictA = {}
for item in config2.items('dict1'):
dictA[item[0]] = item[1]


dictB = {}
for item in config2.items('dict2'):
dictB[item[0]] = item[1]


dictC = {}
for item in config2.items('dict3'):
dictC[item[0]] = item[1]


print(dictA)
print(dictB)
print(dictC)

Python 3。X的例子。

import configparser


config = configparser.ConfigParser()


dict1 = {'key1':'keyinfo', 'key2':'keyinfo2'}
dict2 = {'k1':'hot', 'k2':'cross', 'k3':'buns'}
dict3 = {'x':1, 'y':2, 'z':3}


# Make each dictionary a separate section in the configuration
config['dict1'] = dict1
config['dict2'] = dict2
config['dict3'] = dict3


# Save the configuration to a file
f = open('config.ini', 'w')
config.write(f)
f.close()


# Read the configuration from a file
config2 = configparser.ConfigParser()
config2.read('config.ini')


# ConfigParser objects are a lot like dictionaries, but if you really
# want a dictionary you can ask it to convert a section to a dictionary
dictA = dict(config2['dict1'] )
dictB = dict(config2['dict2'] )
dictC = dict(config2['dict3'])


print(dictA)
print(dictB)
print(dictC)

控制台输出

{'key2': 'keyinfo2', 'key1': 'keyinfo'}
{'k1': 'hot', 'k2': 'cross', 'k3': 'buns'}
{'z': '3', 'y': '2', 'x': '1'}

config.ini的内容

[dict1]
key2 = keyinfo2
key1 = keyinfo


[dict2]
k1 = hot
k2 = cross
k3 = buns


[dict3]
z = 3
y = 2
x = 1

我的用例是将多个JSON对象保存到一个文件中,马蒂的回答在一定程度上帮助了我。但是为了服务于我的用例,答案并不完整,因为每次保存新条目时它都会覆盖旧数据。

要在一个文件中保存多个条目,必须检查旧内容(即先读后写)。保存JSON数据的典型文件将以listobject作为根。所以我认为我的JSON文件总是有一个list of objects,每次我向它添加数据时,我只是先加载列表,在其中追加我的新数据,并将其转储回一个只能写的文件实例(w):

def saveJson(url,sc): # This function writes the two values to the file
newdata = {'url':url,'sc':sc}
json_path = "db/file.json"


old_list= []
with open(json_path) as myfile:  # Read the contents first
old_list = json.load(myfile)
old_list.append(newdata)


with open(json_path,"w") as myfile:  # Overwrite the whole content
json.dump(old_list, myfile, sort_keys=True, indent=4)


return "success"


新的JSON文件看起来像这样:

[
{
"sc": "a11",
"url": "www.google.com"
},
{
"sc": "a12",
"url": "www.google.com"
},
{
"sc": "a13",
"url": "www.google.com"
}
]


注意:必须有一个名为file.json的文件,其中[]作为该方法工作的初始数据

PS:与原始问题无关,但这种方法也可以进一步改进,首先检查我们的条目是否已经存在(基于一个或多个键),然后再追加并保存数据。

较短的代码

保存和加载所有类型的python变量(包括字典),每个变量只需一行代码。

data = {'key1': 'keyinfo', 'key2': 'keyinfo2'}

保存:

pickle.dump(data, open('path/to/file/data.pickle', 'wb'))
   

加载:

data_loaded = pickle.load(open('path/to/file/data.pickle', 'rb'))

也许这很明显,但在我试图使它更短之前,我在顶部的答案中使用了两行解。