如何将字典保存到文件?


139

我在更改dict值并将dict保存到文本文件(格式必须相同)时遇到问题,我只想更改member_phone字段。

我的文本文件是以下格式:

memberID:member_name:member_email:member_phone

我将文本文件拆分为:

mdict={}
for line in file:
    x=line.split(':')
    a=x[0]
    b=x[1]
    c=x[2]
    d=x[3]
    e=b+':'+c+':'+d

    mdict[a]=e

当我尝试更改member_phone存储在中时d,值已更改,无法按键流动,

def change(mdict,b,c,d,e):
    a=input('ID')
    if a in mdict:
        d= str(input('phone'))
        mdict[a]=b+':'+c+':'+d
    else:
        print('not')

以及如何将字典保存到具有相同格式的文本文件中?

Answers:


258

Python 为此提供了pickle模块。

这些功能是保存和加载几乎所有对象所需的全部:

def save_obj(obj, name ):
    with open('obj/'+ name + '.pkl', 'wb') as f:
        pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)

def load_obj(name ):
    with open('obj/' + name + '.pkl', 'rb') as f:
        return pickle.load(f)

这些功能假定您obj在当前工作目录中有一个文件夹,该文件夹将用于存储对象。

请注意,这pickle.HIGHEST_PROTOCOL是一种二进制格式,可能并不总是很方便,但对性能却很有帮助。协议0是一种文本格式。

为了保存Python的集合,有一个shelve模块。


1
save_obj似乎要求该文件obj/'+ name + '.pkl已经存在。我创建了一个名为的字典Q,将其填充,然后打电话给save_obj(Q, "Qtable")我,我得到一个错误:FileNotFoundError: [Errno 2] No such file or directory: 'obj/Qtable.pkl'在写入文件之前,它是如何首先创建文件的?
牙签海葵

1
@ToothpickAnemone用于wb+创建文件,即:with open('obj/'+ name + '.pkl', 'wb+')
andrey.s

1
@ andrey.s:我认为您的发言不会带来任何改变,因为它不能解决问题。
martineau

1
@Toothpick Anemone:+向该模式添加a 对您的问题没有任何影响(andrey.s是不正确的)。您的问题听起来像是因为一两件事。为了使save_obj()该答案起作用,"obj"必须已经存在一个名为的子目录,因为它open()不会自动创建一个子目录。其次,第一个参数save_obj()是要保存的Python对象,而不是子目录的名称(尽管尚不能完全清楚Q示例save_obj(Q, "Qtable")调用中的含义)。如果目录尚未以退出,则可以创建一个目录os.mkdir()
martineau

168

泡菜可能是最好的选择,但是如果有人想知道如何使用NumPy将字典保存并加载到文件中,请执行以下操作:

import numpy as np

# Save
dictionary = {'hello':'world'}
np.save('my_file.npy', dictionary) 

# Load
read_dictionary = np.load('my_file.npy',allow_pickle='TRUE').item()
print(read_dictionary['hello']) # displays "world"

仅供参考:NPY文件查看器


4
.item()的作用是什么?
Gulzar

为什么这个答案不如@Zah的“挑剔”答案高?更复杂的空间?
弥敦道

1
@frank的可能性,因为pickle是python标准库的一部分,其中numpy是一个独立的项目。
Maxim Veksler,

2
从我的@Gulzar看来,np.load返回一个ndarray(这样做是一个type(read_dictionary)揭示),而.item()基本上将该元素转换为python标量对象,这是这里
abhyudayasrinet

2
@Shai您是否安装了numpy软件包...?
伊本

26

json如果字典或其他一些数据可以轻松地映射为JSON格式,我们也可以使用该模块

import json

# Serialize data into file:
json.dump( data, open( "file_name.json", 'w' ) )

# Read data from file:
data = json.load( open( "file_name.json" ) )

该解决方案带来了许多好处,例如,以不变的格式适用于Python 2.xPython 3.x此外,以JSON格式保存的数据可以在许多不同的平台或程序之间轻松传输。这些数据也是人类可读的


好的方法,但是我认为open直接使用代替由创建的上下文并不安全with。是否有保证,如果json.dump失败将关闭文件句柄?
Dr_Zaszuś

18

我不确定您的第一个问题是什么,但是如果要将字典保存到文件中,则应使用该json库。查找负载和放置函数的文档。


为什么是json?使用“ repr”将Python词典转储到文件中甚至更加容易
mguijarr

5
@mguijarr,但是将其解析回来并不容易。Plus json易于手动编辑并导入任何其他程序。
kalhartt

1
我喜欢John的建议-请参阅此帖子,这是一个很好的简单示例stackoverflow.com/a/11027021/765827
jacanterbury 2014年

9

保存字典并将其加载到文件中:

def save_dict_to_file(dic):
    f = open('dict.txt','w')
    f.write(str(dic))
    f.close()

def load_dict_from_file():
    f = open('dict.txt','r')
    data=f.read()
    f.close()
    return eval(data)

3

对于诸如您正在处理的字符串的字典,可以仅使用Python的内置文本处理功能来完成。

(请注意,如果值是其他值,则此方法将无效。)

with open('members.txt') as file:
    mdict={}
    for line in file:
        a, b, c, d = line.strip().split(':')
        mdict[a] = b + ':' + c + ':' + d

a = input('ID: ')
if a not in mdict:
    print('ID {} not found'.format(a))
else:
    b, c, d = mdict[a].split(':')
    d = input('phone: ')
    mdict[a] = b + ':' + c + ':' + d  # update entry
    with open('members.txt', 'w') as file:  # rewrite file
        for id, values in mdict.items():
            file.write(':'.join([id] + values.split(':')) + '\n')

这不工作的字典:file.write( ':'加入([ID] + values.split( ':'))+ '\ n')。AttributeError的: '快译通'对象有没有属性'分裂'
Shai Alon

@ShaiAlon:不是所有人,不是。这肯定不会与那些值是字符串(即有工作split()法) -其这一问题的话题。听起来您正在尝试在字典词典中使用它,所以不,它不适用于那些字典。我也不喜欢人们的不赞成票,因为他们并不真正理解问题(因此也不了解所提供的答案的内容)。我会更新答案以使其在使用时适当,因此请撤消您的不赞成票。
martineau '18年

3

我建议您使用JSON格式而不是pickle格式保存数据,因为JSON的文件易于读​​取,因为您的数据很小,因此使调试更加容易。其他程序还使用JSON文件读取和写入数据。您可以在此处了解更多信息

您需要安装JSON模块,可以使用pip进行安装:

pip install json


# To save the dictionary into a file:
json.dump( data, open( "myfile.json", 'w' ) )

这将创建一个名为myfile的json文件。

# To read data from file:
data = json.load( open( "myfile.json" ) )

这将读取myfile.json数据并将其存储在数据对象中。


2

除非您真的想保留字典,否则我认为最好的解决方案是使用csvPython模块读取文件。然后,您将获得几行数据,并且可以更改member_phone或更改任何内容;最后,您可以使用csv再次模块以与打开文件时相同的格式保存文件。

阅读代码:

import csv

with open("my_input_file.txt", "r") as f:
   reader = csv.reader(f, delimiter=":")
   lines = list(reader)

编写代码:

with open("my_output_file.txt", "w") as f:
   writer = csv.writer(f, delimiter=":")
   writer.writerows(lines)

当然,您需要调整change()功能:

def change(lines):
    a = input('ID')
    for line in lines:
      if line[0] == a:
        d=str(input("phone"))
        line[3]=d
        break
    else:
      print "not"

Of course, you need to adapt your change() function:
kRazzy R

1
在问题中,使用了a dict ,而csv的工作方式更像一个列表
mguijarr

1

我没有计时,但我敢打赌h5比泡菜要快。压缩后的文件大小几乎可以肯定较小。

import deepdish as dd
dd.io.save(filename, {'dict1': dict1, 'dict2': dict2}, compression=('blosc', 9))

-2

快速又肮脏的解决方案:将dict转换为字符串并保存到文件,例如:

#dict could be anything:

savedict = open('savedict001.txt', 'w')
savedict.write(str(dict))
savedict.close()

将dict转换为str并保存不起作用,特别是当您将pd.Series或np.ndarray作为字符串中的键时。
Arpan Srivastava
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.