Chuyển đổi một con trăn thành một chuỗi và trở lại


275

Tôi đang viết một chương trình lưu trữ dữ liệu trong một đối tượng từ điển, nhưng dữ liệu này cần được lưu tại một số điểm trong khi thực hiện chương trình và được tải lại vào đối tượng từ điển khi chương trình được chạy lại. Làm thế nào tôi có thể chuyển đổi một đối tượng từ điển thành một chuỗi có thể được ghi vào một tệp và được tải lại vào một đối tượng từ điển? Điều này hy vọng sẽ hỗ trợ từ điển có chứa từ điển.

Câu trả lời:


272

Các mô-đun json là một giải pháp tốt ở đây. Nó có lợi thế hơn dưa chua là nó chỉ tạo ra đầu ra văn bản đơn giản, và là đa nền tảng và phiên bản chéo.

import json
json.dumps(dict)

2
Tôi cũng sẽ xem xét mô-đun này. Cả json và dưa chua dường như đủ dễ sử dụng, vì vậy nó sẽ đi vào những thứ như hỗ trợ đa nền tảng. Cảm ơn
AJ00200

5
Pickle có xu hướng được coi là khá phản đối vào thời điểm này. Tôi luôn sử dụng json cho những thứ như thế này. Được (tương đối) con người có thể đọc được là một LỚN cộng với phần lớn thời gian.
Tyler Eaves

30
Bạn nên thêm một ví dụ đơn giản để cho phép người dùng xem cách làm điều đó.
Miguel Vazq

1
@TylerEaves Bạn có thể cung cấp ví dụ về cách nó nên được thực hiện.
Boban

1
: trán: đừng quên import jsonnhư tôi đã làm!
Jesse Chisholm

207

Nếu từ điển của bạn không quá lớn, có thể str + eval có thể thực hiện công việc:

dict1 = {'one':1, 'two':2, 'three': {'three.1': 3.1, 'three.2': 3.2 }}
str1 = str(dict1)

dict2 = eval(str1)

print dict1==dict2

Bạn có thể sử dụng ast.literal_eval thay vì eval để bảo mật hơn nếu nguồn không đáng tin cậy.


13
Tôi không thực sự chuẩn bị để đối phó với các khai thác có thể mà điều này có thể đưa vào mã. Tôi không biết json hoặc dưa chua có thể có vấn đề gì, nhưng tôi biết thực tế là eval sẽ nguy hiểm trong trường hợp này.
AJ00200

5
@ AJ00200: và thay thế ast.literal_eval mà tôi đã đề cập?. Từ trợ giúp của Python: "Đánh giá một cách an toàn một nút biểu thức hoặc một chuỗi chứa biểu thức Python. Chuỗi hoặc nút được cung cấp chỉ có thể bao gồm các cấu trúc nghĩa đen của Python sau: chuỗi, số, tuples, danh sách, dicts, booleans và Không có. có thể được sử dụng để đánh giá các chuỗi có chứa các biểu thức Python một cách an toàn mà không cần phải phân tích các giá trị. "
PabloG

Điều này có vẻ hữu ích, nhưng trước đây tôi đã sử dụng SQLite để xử lý dữ liệu này và nó có hơn 1500 mục, vì vậy nó khá lớn và phát triển mọi lúc.
AJ00200

164

Tôi sử dụng json:

import json

# convert to string
input = json.dumps({'id': id })

# load to dict
my_dict = json.loads(input) 

14

Sử dụng picklemô-đun để lưu nó vào đĩa và tải về sau.


2
@extraneon Thật ra, nó là một câu trả lời cho câu hỏi. Nó chuyển đổi nó thành một chuỗi ở đâu đó và ghi nó vào một tập tin. Tôi không phải thực hiện chuyển đổi hoặc viết tập tin thực tế vì tất cả được gói gọn bởi dưa chua.
AJ00200

11

Tại sao không sử dụng chức năng thư viện ast sẵn có của Python 3 lítal_eval . Tốt hơn là sử dụng lítal_eval thay vì eval

import ast
str_of_dict = "{'key1': 'key1value', 'key2': 'key2value'}"
ast.literal_eval(str_of_dict)

sẽ cho đầu ra như từ điển thực tế

{'key1': 'key1value', 'key2': 'key2value'}

Và nếu bạn đang yêu cầu chuyển đổi Từ điển thành Chuỗi thì Làm thế nào về việc sử dụng phương thức str () của Python.

Giả sử từ điển là:

my_dict = {'key1': 'key1value', 'key2': 'key2value'}

Và điều này sẽ được thực hiện như thế này:

str(my_dict)

Sẽ in:

"{'key1': 'key1value', 'key2': 'key2value'}"

Đây là dễ dàng như bạn muốn.


5

Nếu trong Chinses

import codecs
fout = codecs.open("xxx.json", "w", "utf-8")
dict_to_json = json.dumps({'text':"中文"},ensure_ascii=False,indent=2)
fout.write(dict_to_json + '\n')

1
Đây sẽ là một câu trả lời tốt hơn nếu bạn giải thích cách mã bạn cung cấp trả lời câu hỏi.
pppery

4

Chuyển đổi từ điển thành JSON (chuỗi)

import json 

mydict = { "name" : "Don", 
          "surname" : "Mandol", 
          "age" : 43} 

result = json.dumps(mydict)

print(result[0:20])

sẽ có em:

{"tên": "Don", "sur

Chuyển đổi chuỗi thành từ điển

back_to_mydict = json.loads(result) 

3

Tôi nghĩ bạn nên cân nhắc sử dụng shelve mô-đun cung cấp các đối tượng giống như từ điển được hỗ trợ tập tin. Thật dễ dàng để sử dụng thay cho từ điển "thực" vì nó gần như cung cấp cho chương trình của bạn một thứ gì đó có thể được sử dụng giống như từ điển, mà không cần phải chuyển đổi nó thành một chuỗi và sau đó ghi vào một tệp (hoặc ngược lại) ngược lại).

Sự khác biệt chính là cần phải ban đầu open()trước khi sử dụng lần đầu tiên và sau đó close()là khi bạn hoàn thành (và có thể sử dụng sync()nó, tùy thuộc vàowriteback sử dụng tùy chọn được sử dụng). Bất kỳ đối tượng tệp "kệ" nào tạo ra đều có thể chứa từ điển thông thường làm giá trị, cho phép chúng được lồng vào nhau một cách hợp lý.

Đây là một ví dụ tầm thường:

import shelve

shelf = shelve.open('mydata')  # open for reading and writing, creating if nec
shelf.update({'one':1, 'two':2, 'three': {'three.1': 3.1, 'three.2': 3.2 }})
shelf.close()

shelf = shelve.open('mydata')
print shelf
shelf.close()

Đầu ra:

{'three': {'three.1': 3.1, 'three.2': 3.2}, 'two': 2, 'one': 1}

2

Nếu bạn quan tâm đến tốc độ, hãy sử dụng ujson (UltraJSON), có API tương tự như json:

import ujson
ujson.dumps([{"key": "value"}, 81, True])
# '[{"key":"value"},81,true]'
ujson.loads("""[{"key": "value"}, 81, true]""")
# [{u'key': u'value'}, 81, True]

1

Tôi sử dụng yaml cho điều đó nếu cần có thể đọc được (cả JSON và XML đều không phải là IMHO) hoặc nếu không cần đọc thì tôi sử dụng dưa chua.

Viết

from pickle import dumps, loads
x = dict(a=1, b=2)
y = dict(c = x, z=3)
res = dumps(y)
open('/var/tmp/dump.txt', 'w').write(res)

Đọc lại

from pickle import dumps, loads
rev = loads(open('/var/tmp/dump.txt').read())
print rev

Bạn thực sự nên sử dụng bcờ khi mở tập tin ở đây.
Piotr Dobrogost

1
Tôi có thể đã rõ ràng hơn. Tuy nhiên, dumps()mặc định là giao thức 0, là giao thức ascii. Đó là lý do tại sao 'rb'IMHO không cần thiết.
Gerard
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.