71 votes

json sérialise un dictionnaire avec des tuples comme clé

Existe-t-il un moyen en Python de sérialiser un dictionnaire qui utilise un tuple comme clé :

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

en utilisant simplement json.dumps(a), produit :

 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

45voto

IfLoop Points 59461

Vous ne pouvez pas sérialiser cela en tant que json, json a une idée beaucoup moins flexible de ce qui compte comme clé dict que python.

Vous pouvez transformer le mappage en une séquence de paires clé, valeur, quelque chose comme ceci :

 >>> 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]}]'

14voto

markling Points 593
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()}

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

10voto

Dhiraj Thakur Points 140

Vous pouvez simplement utiliser str((1,2)) comme clé car json n'attend les clés que sous forme de chaînes, mais si vous l'utilisez, vous devrez utiliser a[str((1,2))] pour obtenir la valeur.

8voto

Ned Batchelder Points 128913

JSON ne prend en charge que les chaînes en tant que clés. Vous devrez choisir un moyen de représenter ces tuples sous forme de chaînes.

3voto

thebeancounter Points 705

json ne peut accepter que des chaînes comme clés pour dict, ce que vous pouvez faire, c'est de remplacer les clés de tuple par une chaîne comme ceci

 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) 

Et que lorsque vous voulez le lire, vous pouvez changer les clés en tuples en utilisant

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X