2013-04-14 15 views
5

json.dumpsを使用してPythonオブジェクトをJSONにシリアル化しようとしています。 json.dumpsを使用してdictをシリアル化する場合、明らかにJSON辞書{..}としてシリアル化されます。 listまたはtupleをシリアル化すると、JSON配列になります。可能であれば、Python dictをリストとしてJSONに変換する方法

可能であれば、Python dictをJSON listとして簡単にシリアル化する方法があるかどうかを知りたいと思います。

{0:'data',1:'data',2:'data} 

上記のようにJSONにシリアライズされます::'{"0": "data", "1": "data", "2": "data"}'が、私はそれがキー以来['data','data','data']としてシリアライズされたいキーは0から開始し、例えば、配列決定されている場合は、可能であれば、私は意味します0から始まり、シーケンスされます。

私は、PHPからシリアル化されたたくさんのJSONデータがあるためです.PHP配列にはキーがあり、上記のようにキーの順序が決められていれば、PHPのjson.encodeは配列を使用しますJSONディクショナリとしてシリアル化されています。 JSONのシリアル化をPHPとPythonのコードの両方に一致させたい残念ながら、私の場合、PHPコードの変更はオプションではありません。

提案がありますか?私が見つけた唯一の解決策は、それぞれのPython辞書を検証し、最初にlistに変換してjson.dumpsの前に変換できるかどうかを確認する独自の関数を書くことです。

EDIT:私はシリアル化しています。このオブジェクトは、それはように、追加のそれの内部dicts、およびリスト、および(ネスティング)を持つことができるだけでなくlistまたはdict、可能性があります。私は、これを行うための "シンプルな"方法があるのだろうかと思っています。そうでなければ、自分で再帰的な解決法を書くことができると思います。しかし、より多くのバグを避けるために既存のコードを使用する方が常に良いです。

+0

'dict.values()'がpy3kで動作するかどうかはわかりません。また、FWIWのdictsは順序付けされたデータ型ではないので、json.dumps(list(dict.values()))を実行しても、シリアル化されたリストの順序はよく定義されますが、 – mgilson

答えて

3

私は再帰なしで解決策を知りませんが、あなたのカスタムEncoderencode方法の中から、あなたのコンバータを呼び出すことができますが、それだけで不必要な複雑さを追加します... 。

In [1]: import json 

In [2]: d = {"0": "data0", "1": "data1", "2": {"0": "data0", "1": "data1", "2": "data2"}} 

In [3]: def convert(obj): 
    ...:  if isinstance(obj, (list, tuple)): 
    ...:   return [convert(i) for i in obj] 
    ...:  elif isinstance(obj, dict): 
    ...:   _, values = zip(*sorted(obj.items())) 
    ...:   return convert(values) 
    ...:  return obj 

In [4]: json.dumps(convert(d)) 
Out[4]: '["data0", "data1", ["data0", "data1", "data2"]]' 
2

辞書項目は必ずしもあなたがそれらをしたいよりも、順番に出てこないだろうとあなたは、タプルのリストに辞書を変換し、それを並べ替えることができます:通常、あなたがjson.JSONEncoderをサブクラス化することができ

items = sorted(d.items(), key=lambda item: item[0]) 
values = [item[1] for item in items] 
json_dict = json.dumps(values) 
1

独自のカスタムJSONシリアライザを作成しますが、組み込みオブジェクト型をオーバーライドすることはできません。

あなたがあなた自身のカスタムJSONシリアライザを作成するためのJSONEncoder.defaultメソッドをオーバーライドすることができるはずlistdictを延長するか、しない(あなたがそれを呼び出すために好きか)独自のカスタムdictlistオブジェクトを作成する場合。

にかかわらず、カスタムJSONシリアライザを作成したり、再帰的にリストをあなたの特別なdictインスタンスを置き換えるかどうかの、あなたはdictを受け入れ、listまたはdictとして適切なのいずれかを返す関数が必要になります。

ここに1つの実装です:

def convert_to_list(obj): 
    obj_list = [] 
    for i in range(len(obj)): 
     if i not in obj: 
      return obj # Return original dict if not an ordered list 
     obj_list.append(obj[i]) 
    return obj_list 
関連する問題