2013-04-14 7 views
5

Próbuję serializować moje obiekty Python do JSON przy użyciu json.dumps. Jeśli serializuje się dict przy użyciu json.dumps, będzie to oczywiście serializowane jako słownik JSON {..}; jeśli serializuje się list lub tuple, będzie to tablica JSON.Jak przekonwertować Dython Dython do JSON jako listę, jeśli to możliwe

Chcę się dowiedzieć, czy istnieje jakikolwiek sposób łatwego serializowania Pythona dict jako JSON list, jeśli to możliwe. Przez jeśli to możliwe, to znaczy wtedy, gdy klucze zaczynają się od 0 i są wyświetlane sekwencyjnie, na przykład:

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

Powyższy byłoby serializacji do JSON jako: '{"0": "data", "1": "data", "2": "data"}', ale chciałbym to być szeregowane jako ['data','data','data'] od kluczy zaczynają się od 0 i są sekwencjonowane.

Moje rozumowanie polega na tym, że mam dużo danych JSON, które są serializowane z PHP, gdzie w macierzy PHP są klucze i jeśli klucze są sekwencjonowane jak opisano powyżej, PHP json.encode używa tablic, jeśli są one wpisane w inne są serializowane jako słowniki JSON. Chcę, aby moje serializacje JSON pasowały do ​​mojego kodu PHP i Pythona. Niestety zmiana kodu PHP nie jest możliwa w moim przypadku.

Wszelkie sugestie? Jedyne rozwiązanie, jakie znalazłem, to napisanie własnej funkcji sprawdzania każdego słownika Pythona i sprawdzania, czy najpierw można go przekonwertować na list przed json.dumps.

EDIT: To obiekt, który mam szeregowania może być list lub dict, jak dobrze, to może mieć dodatkowe dicts wewnątrz niego i list, i tak dalej (zagnieżdżenia). Zastanawiam się, czy istnieje jakiś "prosty" sposób, aby to zrobić, w przeciwnym razie wierzę, że sam mogę napisać rozwiązanie rekurencyjne. Ale zawsze lepiej jest używać istniejącego kodu, aby uniknąć kolejnych błędów.

+0

Nie jestem pewien, czy 'dict.values ​​()' będzie działać w py3k. Ponadto, FWIW, dykty nie są uporządkowanym typem danych, więc kolejność zserializowanej listy będzie dobrze zdefiniowana, ale "dowolna", nawet jeśli zrobisz 'json.dumps (list (dict.values ​​())) – mgilson

Odpowiedz

3

nie wiem roztworu bez rekursji ... Chociaż można połączyć się z konwertera od wewnątrz metody swojego zwyczaju Encoderencode, to wystarczy dodać niepotrzebnej złożoności .

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

Można przekonwertować słownika na listę krotek, a następnie posortować je, jako słownika przedmioty niekoniecznie wyjdzie w kolejności niż chcesz im:

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

Normalnie można podklasy json.JSONEncoder do utwórz własny niestandardowy seriser JSON, ale to nie pozwoli ci przesłonić wbudowanych typów obiektów.

Jeśli tworzyć własne dictlist obiekt (lub cokolwiek chcesz to nazwać), który nie rozciąga dict lub list powinieneś być w stanie zastąpić metodę JSONEncoder.default aby tworzyć własne serializatora JSON.

Niezależnie od tego, czy stworzenie własnego JSON serializatora lub rekurencyjnie zastąpić specjalne dict instancji z listy trzeba będzie funkcję, która akceptuje dict i zwraca albo list lub dict jako właściwe.

Oto jeden realizacja:

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 
Powiązane problemy