사전을 파일로 저장하는 방법?


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')

그리고 같은 형식의 텍스트 파일에 dict를 저장하는 방법은 무엇입니까?

답변:


258

파이썬에는 이런 종류의 피클 모듈이 있습니다.

이러한 기능은 거의 모든 객체를 저장하고로드하는 데 필요한 모든 것입니다.

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은 텍스트 형식입니다.

파이썬 컬렉션을 저장하기 위해 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()는 서브 디렉토리의 이름이 아니라 저장 될 파이썬 객체입니다 ( Q예제 save_obj(Q, "Qtable")호출 에서 당신이 의미하는 바가 완전히 명확하지는 않지만 ). 로 끝나지 않으면 디렉토리를 만들 수 있습니다 os.mkdir().
martineau

168

Pickle이 가장 좋은 옵션 일 수 있지만 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의 "pickle"답변보다 덜지지 되는가? 더 복잡한 공간?
Nathan

1
pickle은 numpy가 독립적 인 프로젝트 인 python의 표준 라이브러리의 일부이기 때문에 @frank 가능성.
Maxim Veksler

2
내가 고개를 무엇 np.load 다시 표시 ndarray에서 @Gulzar (A는 일을 type(read_dictionary)그렇게 계시)과 .item ()는 기본적으로 명시된 사전 인 파이썬 스칼라 객체에 해당 요소로 변환 여기를
abhyudayasrinet

2
@Shai numpy 패키지를 설치 했습니까?
Eben

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" ) )

이 솔루션은 많은 혜택 제공 , 예를 들면 위한 작품 파이썬 2.X파이썬 3.x의 변경되지 않은 형태 로 저장뿐만 아니라, 데이터를 JSON의 형식이 될 수 쉽게 다양한 플랫폼 또는 프로그램간에 전송을 . 이 데이터는 사람이 읽을 수 있습니다.


좋은 접근 방법이지만에 open의해 작성된 컨텍스트 대신 직접 사용하는 것이 안전하다고 생각하지 않습니다 with. 보증인 json.dump이 있습니까 , 실패하면 파일 핸들이 닫힙니 까?
Dr_Zaszuś

18

첫 번째 질문이 무엇인지 잘 모르겠지만 사전을 파일로 저장하려면 json라이브러리를 사용해야합니다 . 로드 및 풋 기능에 대한 문서를 찾아보십시오.


왜 JSON입니까? "repr"을 사용하여 파이썬 사전을 파일로 덤프하는 것이 훨씬 쉽습니다
mguijarr

5
@mguijarr 그러나 다시 파싱하는 것은 쉽지 않습니다. 또한 json은 손으로 쉽게 편집하고 다른 프로그램으로 가져올 수 있습니다.
kalhartt

1
나는 John의 제안을 좋아한다-이 글에서 좋은 간단한 예제를보십시오. stackoverflow.com/a/11027021/765827
jacanterbury

9

dict을 파일에 저장하고로드하십시오.

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 ( ':'. join ([id] + values.split ( ':')) + '\ n') AttributeError : 'dict'객체에 'split'속성이 없습니다.
Shai Alon

@ShaiAlon : 그들 모두가 아닙니다. 이 질문의 주제 인 값이 문자열 인 ( 메소드 가있는 ) 값에 대해서는 확실히 작동 합니다 split(). 사전 사전에서 사용하려고하는 것처럼 들리므로 작동하지 않습니다. 또한 사람들이 질문을 실제로 이해하지 못하기 때문에 (투표 된 답변의 맥락) 이해하지 못하는 사람들의 투표에 감사하지 않습니다. 적절하게 사용할 수 있도록 답변을 업데이트하겠습니다. 따라서 투표를 취소하십시오.
martineau

3

JSON 파일은 사람이 읽을 수 있으므로 데이터가 작기 때문에 디버깅이 더 쉬워 지므로 피클 형식 대신 JSON 형식을 사용하여 데이터를 저장하는 것이 좋습니다. JSON 파일은 다른 프로그램에서도 데이터를 읽고 쓰는 데 사용됩니다. 자세한 내용은 여기를 참조하십시오

pip로 JSON 모듈을 설치해야합니다.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.