2011-08-09 9 views
34

रूप tuples के साथ एक शब्दकोश को क्रमानुसार वहाँ पायथन में एक तरह से एक शब्दकोश है कि कुंजी के रूप में एक टपल उपयोग कर रहा है क्रमानुसार करने है:json कुंजी

:

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

बस json.dumps (क), पैदा करता है का उपयोग करते हुए

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

[जेसन के साथ tuples एन्कोड करने के लिए सबसे अच्छा तरीका] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/715550/best-way-to-encode-tuples-with-json) – agf

उत्तर

19

आप जेसन के रूप में क्रमबद्ध नहीं कर सकते हैं, जेसन के पास पाइथन की तुलना में एक कोर कुंजी के रूप में कितना मायने रखता है, इस बारे में बहुत कम लचीला विचार है।

आप इस तरह कुंजी, मान के जोड़े, कुछ के अनुक्रम में रखता मानचित्रण परिवर्तित कर:

>>> 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 केवल तारों के रूप में स्ट्रिंग का समर्थन करता है। आपको तारों के रूप में उन tuples का प्रतिनिधित्व करने के लिए एक रास्ता चुनने की आवश्यकता होगी।

1

यहाँ एक तरह से यह करने के लिए है। यह आवश्यकता होगी के बाद मुख्य शब्दकोश डीकोड और पूरे शब्दकोश फिर से अनुक्रम कुंजी json डीकोड किया जा करने के लिए, लेकिन यह संभव है:

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

मैं इस विधि के किसी भी दक्षता के लिए कोई दावा नहीं कर सकते हैं। मुझे कुछ जॉयस्टिक मैपिंग डेटा को फ़ाइल में सहेजने के लिए इसकी आवश्यकता थी। मैं ऐसा कुछ उपयोग करना चाहता था जो अर्ध-मानव पठनीय प्रारूप बनाएगा ताकि इसे आवश्यकतानुसार संपादित किया जा सके।

3

आप सिर्फ इसलिए कि json केवल तारों के रूप में चाबियाँ उम्मीद कुंजी के रूप में इस्तेमाल कर सकते हैं str((1,2)) लेकिन यदि आप इस का उपयोग आप a[str((1,2))] उपयोग करने के लिए मूल्य प्राप्त करना होगा।

0

json केवल dict के लिए कुंजी के रूप में तार स्वीकार कर सकते हैं, आप क्या कर सकते हैं, इसलिए

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) 

की तरह और की तुलना में जब आप इसे पढ़ना चाहते हैं तार के साथ टपल कुंजियों को बदलने के लिए है, तो आप बदल सकते हैं tuples को वापस कुंजियों का उपयोग

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()} 

देखें: https://stackoverflow.com/a/12337657/2455413

संबंधित मुद्दे