json serialize a dictionary with tuples as key
Python中是否有一种方法可以序列化使用元组作为键的字典:
1 | a={(1,2):'a'} |
只需使用json.dumps(a),就会产生:
1 2 3 4 5 6 7 8 9 10 11 | 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 |
您不能将其序列化为json,json对于什么算作dict键要比python灵活得多。
您可以将映射转换为键,值对的序列,如下所示:
1 2 3 4 5 6 | >>> 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]}]' |
JSON仅支持将字符串作为键。您需要选择一种将这些元组表示为字符串的方式。
您可以只将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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()} |
参见:https://stackoverflow.com/a/12337657/2455413
json只能接受字符串作为字典的键,
您可以做的是用这样的字符串替换元组键
1 2 3 4 5 | 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) |
而且,当您要阅读它时,可以使用以下命令将键改回元组
1 2 3 4 5 6 7 | 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])) |
这是一种方法。在解码主字典并重新排序整个字典之后,将要求对密钥进行json解码,但这是可行的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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() |
我不主张这种方法的任何效率。我需要用它来保存一些操纵杆映射数据到文件。我想使用可以创建半人类可读格式的东西,以便在需要时可以对其进行编辑。