2013-04-14 40 views
5

Tôi đang cố gắng tuần tự hóa các đối tượng Python của mình vào JSON bằng cách sử dụng json.dumps. Nếu bạn tuần tự hóa một dict sử dụng json.dumps, nó rõ ràng sẽ được tuần tự hóa dưới dạng từ điển JSON {..}; nếu bạn tuần tự hóa list hoặc tuple, nó sẽ là một mảng JSON.Làm thế nào để chuyển đổi Python dict sang JSON dưới dạng danh sách, nếu có thể

Tôi muốn biết nếu có bất kỳ cách nào để dễ dàng tuần tự hóa một Python dict dưới dạng JSON list, nếu có thể. Bởi nếu có thể, tôi có nghĩa là nếu các phím bắt đầu từ 0 và được sắp xếp, ví dụ:

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

Trên đây sẽ được tuần tự vào JSON như: '{"0": "data", "1": "data", "2": "data"}', nhưng tôi muốn nó được tuần tự như ['data','data','data'] từ các phím bắt đầu từ 0 và được sắp xếp theo trình tự. Lý do của tôi cho điều này là vì tôi có rất nhiều dữ liệu JSON được tuần tự hóa từ PHP, trong đó các mảng PHP có khóa và nếu các khóa được sắp xếp theo trình tự như trên, PHP json.encode sử dụng mảng, nếu chúng được khóa theo cách thức, chúng được tuần tự hóa dưới dạng từ điển JSON. Tôi muốn serialization JSON của tôi để phù hợp cho cả hai mã PHP và Python của tôi. Thật không may, việc thay đổi mã PHP không phải là một tùy chọn trong trường hợp của tôi.

Mọi đề xuất? Giải pháp duy nhất tôi đã tìm thấy là viết chức năng của riêng tôi để đi qua và xác minh từng từ điển python và xem liệu nó có thể được chuyển đổi thành list trước json.dumps hay không.

EDIT: Đối tượng này mà tôi serializing có thể là một list hoặc một dict, là tốt, nó có thể có thêm dicts bên trong của nó, và danh sách, và vân vân (tổ). Tôi tự hỏi nếu có cách nào đơn giản để làm điều này, nếu không tôi tin rằng tôi có thể viết một giải pháp đệ quy bản thân mình. Nhưng nó luôn luôn tốt hơn để sử dụng mã hiện có để tránh lỗi hơn.

+0

Tôi không chắc chắn nếu 'dict.values ​​()' sẽ hoạt động trong py3k. Ngoài ra, FWIW, dicts không phải là kiểu dữ liệu được sắp xếp, do đó thứ tự của danh sách được sắp xếp theo thứ tự sẽ được xác định rõ, nhưng "tùy ý" ngay cả khi bạn làm 'json.dumps (list (dict.values ​​()))' – mgilson

Trả lời

3

Tôi không biết một giải pháp mà không đệ quy ... Mặc dù bạn có thể gọi chuyển đổi của bạn từ bên trong phương pháp encode tùy chỉnh của bạn Encoder, nó sẽ chỉ cần thêm sự phức tạp không cần thiết .

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

Bạn có thể chuyển đổi từ điển vào một danh sách các hàng và sau đó sắp xếp nó, như các mục từ điển sẽ không nhất thiết phải đi ra theo trình tự hơn bạn muốn họ:

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

Thông thường bạn có thể phân lớp json.JSONEncoder để tạo bộ nối tiếp JSON tùy chỉnh của riêng bạn, nhưng điều đó sẽ không cho phép bạn ghi đè các loại đối tượng dựng sẵn.

Nếu bạn tạo riêng đối tượng của bạn tùy chỉnh dictlist (hoặc bất cứ điều gì bạn muốn gọi nó) mà không mở rộng dict hoặc list bạn sẽ có thể ghi đè lên JSONEncoder.default phương pháp để tạo tùy chỉnh riêng JSON serializer của bạn.

Bất kể bạn tạo ra một tùy chỉnh JSON serializer hoặc đệ quy thay thế đặc biệt dict trường hợp của bạn với danh sách mà bạn sẽ cần một chức năng chấp nhận một dict và trả về một tập list hoặc một dict cho phù hợp.

Đây là một thực hiện:

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 
Các vấn đề liên quan