Làm thế nào để lưu một từ điển vào một tập tin?


139

Tôi gặp vấn đề với việc thay đổi giá trị dict và lưu dict vào tệp văn bản (định dạng phải giống nhau), tôi chỉ muốn thay đổi member_phonetrường.

Tệp văn bản của tôi là định dạng sau:

memberID:member_name:member_email:member_phone

và tôi chia tệp văn bản với:

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

Khi tôi thử thay đổi member_phonelưu trữ trong d, giá trị đã thay đổi không chảy theo khóa,

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

và làm thế nào để lưu dict vào một tệp văn bản có cùng định dạng?

Câu trả lời:


258

Python có mô-đun dưa chua chỉ dành cho loại điều này.

Các chức năng này là tất cả những gì bạn cần để lưu và tải hầu hết mọi đối tượng:

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)

Các hàm này giả định rằng bạn có một objthư mục trong thư mục làm việc hiện tại của bạn, chúng sẽ được sử dụng để lưu trữ các đối tượng.

Lưu ý rằng đó pickle.HIGHEST_PROTOCOLlà định dạng nhị phân, không phải lúc nào cũng thuận tiện, nhưng tốt cho hiệu suất. Giao thức 0là một định dạng văn bản.

Để tiết kiệm bộ sưu tập của Python có sự xiên module.


1
save_objdường như yêu cầu các tập tin obj/'+ name + '.pklđã tồn tại. Tôi đã tạo một từ điển có tên Q, điền vào nó và thực hiện cuộc gọi save_obj(Q, "Qtable")mà tôi gặp lỗi: FileNotFoundError: [Errno 2] No such file or directory: 'obj/Qtable.pkl'Làm thế nào để tạo một tệp ở vị trí đầu tiên trước khi ghi vào nó?
Tăm Anemone

1
@ToothpickAnemone sử dụng wb+để tạo tệp, tức là:with open('obj/'+ name + '.pkl', 'wb+')
andrey.s

1
@ andrey.s: Tôi không nghĩ những gì bạn nói sẽ tạo ra bất kỳ sự khác biệt nào vì nó không giải quyết được vấn đề.
martineau

1
@Toothpick Anemone: Thêm một +chế độ sẽ không ảnh hưởng đến vấn đề của bạn (andrey.s không chính xác). Vấn đề của bạn có vẻ như là do một hoặc hai điều. Để save_obj()câu trả lời này hoạt động, một thư mục con có tên "obj"phải tồn tạiopen()sẽ không tự động tạo một thư mục . Đối số thứ hai save_obj()là đối tượng Python được lưu, không phải tên của thư mục con (mặc dù nó không hoàn toàn rõ ràng ý của bạn Qtrong save_obj(Q, "Qtable")cuộc gọi ví dụ ). Bạn có thể tạo một thư mục nếu nó chưa thoát os.mkdir().
martineau

168

Pickle có lẽ là lựa chọn tốt nhất, nhưng trong trường hợp bất kỳ ai cũng tự hỏi làm thế nào để lưu và tải từ điển vào một tệp bằng 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"

FYI: Trình xem tệp NPY


4
.item () dùng để làm gì?
Gulzar

Tại sao câu trả lời này ít được nâng cao hơn câu trả lời "dưa chua" của @Zah? Không gian phức tạp hơn?
Nathan

1
@frank khả năng vì dưa chua là một phần của thư viện tiêu chuẩn của python trong đó numpy là một dự án độc lập.
Maxim Veksler

2
@Gulzar từ những gì tôi đã tìm kiếm, np.load trả về một ndarray (thực hiện một type(read_dictionary)tiết lộ như vậy) và .item () về cơ bản chuyển đổi phần tử đó thành một đối tượng vô hướng python là một từ điển như đã nêu ở đây
abhyudayasrinet

2
@Shai bạn đã cài đặt gói numpy ...?
Eben

26

Chúng ta cũng có thể sử dụng jsonmô-đun trong trường hợp khi từ điển hoặc một số dữ liệu khác có thể dễ dàng được ánh xạ sang định dạng 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" ) )

Giải pháp này mang lại nhiều lợi ích , ví dụ như hoạt động cho Python 2.xPython 3.x ở dạng không thay đổi và ngoài ra, dữ liệu được lưu ở định dạng JSON có thể dễ dàng được chuyển giữa nhiều nền tảng hoặc chương trình khác nhau . Dữ liệu này cũng có thể đọc được .


Cách tiếp cận tốt, nhưng tôi không nghĩ rằng an toàn khi sử dụng opentrực tiếp thay vì bối cảnh được tạo bởi with. Có một gurantee, xử lý tập tin sẽ bị đóng nếu json.dumpthất bại?
Dr_Zaszuś

18

Tôi không chắc câu hỏi đầu tiên của bạn là gì, nhưng nếu bạn muốn lưu từ điển vào tập tin, bạn nên sử dụng jsonthư viện. Tra cứu tài liệu về tải và đặt các chức năng.


Tại sao json? Thậm chí còn dễ dàng hơn khi chỉ cần đổ từ điển Python vào một tệp bằng cách sử dụng "repr"
mguijarr

5
@mguijarr nhưng phân tích lại nó không dễ như vậy. Plus json dễ dàng chỉnh sửa bằng tay và nhập vào bất kỳ chương trình nào khác.
kalhartt

1
Tôi thích đề xuất của John - xem bài đăng này để biết ví dụ tốt và đơn giản stackoverflow.com/a/11027021/765827
jacanterbury

9

Lưu và tải dict vào tập tin:

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

Đối với một từ điển các chuỗi như chuỗi bạn đang xử lý, có thể được thực hiện bằng cách chỉ sử dụng các khả năng xử lý văn bản tích hợp của Python.

(Lưu ý điều này sẽ không hoạt động nếu các giá trị là thứ khác.)

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

Điều này không hoạt động trên từ điển: file.write (':'. Tham gia ([id] + value.split (':')) + '\ n') AttributionError: đối tượng 'dict' không có thuộc tính 'split'
Shai Alon

@ShaiAlon: Không phải với tất cả bọn họ, không. Nó chắc chắn không làm việc với những người có giá trị là chuỗi (có một split()phương pháp) -which là chủ đề của câu hỏi này. Có vẻ như bạn đang cố gắng sử dụng nó trong một cuốn từ điển từ điển, vì vậy không nó sẽ không hoạt động với những từ đó. Tôi cũng không đánh giá cao sự bình chọn từ mọi người vì họ không thực sự hiểu câu hỏi (và do đó bối cảnh của các câu trả lời được cung cấp). Tôi sẽ cập nhật câu trả lời của mình để đưa ra khi sử dụng nó sẽ phù hợp, vì vậy vui lòng hoàn tác bỏ phiếu của bạn.
martineau

3

Tôi sẽ đề nghị lưu dữ liệu của bạn bằng định dạng JSON thay vì định dạng dưa chua vì các tệp của JSON có thể đọc được bằng con người, giúp việc gỡ lỗi của bạn dễ dàng hơn vì dữ liệu của bạn nhỏ. Các tệp JSON cũng được các chương trình khác sử dụng để đọc và ghi dữ liệu. Bạn có thể đọc thêm về nó ở đây

Bạn sẽ cần cài đặt mô-đun JSON, bạn có thể làm như vậy với pip:

pip install json


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

Điều này tạo ra một tệp json với tên myfile.

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

Điều này đọc và lưu trữ dữ liệu myfile.json trong một đối tượng dữ liệu.


2

Trừ khi bạn thực sự muốn giữ từ điển, tôi nghĩ giải pháp tốt nhất là sử dụng csvmô-đun Python để đọc tệp. Sau đó, bạn nhận được các hàng dữ liệu và bạn có thể thay đổi member_phonehoặc bất cứ điều gì bạn muốn; cuối cùng, bạn có thể sử dụng lại csvmô-đun để lưu tệp theo cùng định dạng như bạn đã mở.

Mã để đọc:

import csv

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

Mã để viết:

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

Tất nhiên, bạn cần điều chỉnh change()chức năng của mình :

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"

có nghĩa là gìOf course, you need to adapt your change() function:
kRazzy R

1
trong câu hỏi, a dict đã được sử dụng trong khi csv hoạt động giống như một danh sách
mguijarr

1

Tôi đã không hẹn giờ nhưng tôi cá là h5 nhanh hơn dưa chua; kích thước tập tin với nén gần như chắc chắn là nhỏ hơn.

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

-2

Giải pháp nhanh và bẩn: chuyển đổi dict thành chuỗi và lưu vào tệp, ví dụ:

#dict could be anything:

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

Chuyển đổi dict thành str và lưu không hoạt động đặc biệt là khi bạn có pd.Series hoặc np.ndarray làm khóa của bạn trong chuỗi.
Arpan Srivastava
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.