2011-08-09 27 views
34

Có cách nào bằng Python để serialize một cuốn từ điển đó là sử dụng một tuple như chính:json serialize một cuốn từ điển với các bộ như chìa khóa

a={(1,2):'a'} 

chỉ đơn giản là sử dụng json.dumps (a), sản xuất:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/json/__init__.py", line 230, in dumps 
    return _default_encoder.encode(obj) 
    File "/usr/lib/python2.6/json/encoder.py", line 367, in encode 
    chunks = list(self.iterencode(o)) 
    File "/usr/lib/python2.6/json/encoder.py", line 309, in _iterencode 
    for chunk in self._iterencode_dict(o, markers): 
    File "/usr/lib/python2.6/json/encoder.py", line 268, in _iterencode_dict 
    raise TypeError("key {0!r} is not a string".format(key)) 
TypeError: key (1, 2) is not a string 
+1

có thể trùng lặp của [Cách tốt nhất để mã hóa các bộ dữ liệu với json] (http://stackoverflow.com/questions/715550/best-way-to-encode-tuples-with-json) – agf

Trả lời

19

Bạn không thể tuần tự hóa như json, json có một ý tưởng ít linh hoạt hơn về những gì được tính là khóa chính tả hơn python.

Bạn có thể biến đổi ánh xạ vào một chuỗi các trọng điểm, các cặp giá trị, một cái gì đó như thế này:

>>> import json 
>>> def remap_keys(mapping): 
...  return [{'key':k, 'value': v} for k, v in mapping.iteritems()] 
... 
>>> json.dumps(remap_keys({(1, 2): 'foo'})) 
'[{"value": "foo", "key": [1, 2]}]' 
7

JSON chỉ hỗ trợ chuỗi làm khóa. Bạn sẽ cần phải chọn một cách để biểu diễn những bộ dữ liệu đó dưới dạng chuỗi.

1

Dưới đây là một cách để làm điều đó. Nó sẽ đòi hỏi chìa khóa để được giải mã json sau khi từ điển chính được giải mã và cả từ điển tái lập trình tự, nhưng nó là doable:

import json 

    def jsonEncodeTupleKeyDict(data): 
     ndict = dict() 
     # creates new dictionary with the original tuple converted to json string 
     for key,value in data.iteritems(): 
      nkey = json.dumps(key) 
      ndict[nkey] = value 

     # now encode the new dictionary and return that 
     return json.dumps(ndict) 

    def main(): 
     tdict = dict() 
     for i in range(10): 
      key = (i,"data",5*i) 
      tdict[key] = i*i 

     try: 
      print json.dumps(tdict) 
     except TypeError,e: 
      print "JSON Encode Failed!",e 

     print jsonEncodeTupleKeyDict(tdict) 

    if __name__ == '__main__': 
     main() 

Tôi không nói tôi cho bất kỳ hiệu quả của phương pháp này. Tôi cần điều này để lưu một số dữ liệu ánh xạ phím điều khiển vào một tệp. Tôi muốn sử dụng một cái gì đó mà sẽ tạo ra một định dạng có thể đọc được nửa người để nó có thể được chỉnh sửa nếu cần thiết.

3

Bạn chỉ có thể sử dụng str((1,2)) làm khóa vì json chỉ dự kiến ​​khóa là chuỗi nhưng nếu bạn sử dụng, bạn sẽ phải sử dụng a[str((1,2))] để nhận giá trị.

0

json chỉ có thể chấp nhận các chuỗi như là chìa khóa cho dict, những gì bạn có thể làm, là để thay thế các phím tuple với chuỗi như vậy

with open("file", "w") as f: 
    k = dic.keys() 
    v = dic.values() 
    k1 = [str(i) for i in k] 
    json.dump(json.dumps(dict(zip(*[k1,v]))),f) 

Và so với khi bạn muốn đọc nó, bạn có thể thay đổi phím trở lại tuples sử dụng

with open("file", r) as f: 
    data = json.load(f) 
    dic = json.loads(data) 
    k = dic.keys() 
    v = dic.values() 
    k1 = [eval(i) for i in k] 
    return dict(zip(*[k1,v])) 
1
from json import load, dump 
from ast import literal_eval 

x={ (0,1):'la-la la', (0,2):'extricate' } 

# save: convert each tuple key to a string before saving as json object 
with open('/tmp/test', 'w') as f: dump({str(k):v for k, v in x.items()}, f) 

# load in two stages:# 
# (i) load json object 
with open('/tmp/test', 'r') as f: obj = load(f) 

# (ii) convert loaded keys from string back to tuple 
d={literal_eval(k):v for k, v in obj.items()} 

Xem: https://stackoverflow.com/a/12337657/2455413

Các vấn đề liên quan