2012-01-30 54 views
10

Tôi muốn chuyển đổi một POST từ Webob MultiDict thành từ điển lồng nhau. Ví dụ.Cách chuyển đổi một MultiDict thành từ điển lồng nhau

Vì vậy, từ một POST của:

'name=Kyle&phone.number=1234&phone.type=home&phone.number=5678&phone.type=work' 

đến một multidict;

[('name', 'Kyle'), ('phone.number', '1234'), ('phone.type', 'home'), ('phone.number', '5678'), ('phone.type', 'work')] 

để một cuốn từ điển lồng nhau

{'name': 'Kyle', 
'phone': [ 
    { 
    'number': '12345', 
    'type': 'home', 
    },{ 
    'number': '5678', 
    'type': 'work', 
    }, 

Bất kỳ ý tưởng?

EDIT

tôi đã kết thúc giải nén các phương pháp variable_decode từ gói formencode như được đăng bởi Will. Thay đổi duy nhất được yêu cầu là làm cho danh sách rõ ràng, Ví dụ:

'name=Kyle&phone-1.number=1234&phone-1.type=home&phone-2.number=5678&phone-2.type=work' 

Điều nào tốt hơn vì nhiều lý do.

+0

Ngoài ra hãy xem tại hạt tiêu từ Dự án Pylons: http://docs.pylonsproject.org/projects/peppercorn/en/latest/ nó đòi hỏi phải rõ ràng hơn trong khi xây dựng các biểu mẫu của bạn, nhưng cho phép tùy ý làm tổ. –

Trả lời

10

Nếu bạn đã formencode cài đặt hoặc có thể cài đặt nó, kiểm ra họ variabledecode module

+0

Tôi trích xuất phương thức variable_decode() và nó hoạt động, hoàn hảo, cảm ơn bạn. –

1

Tôi đã không có thời gian để kiểm tra nó và nó khá hạn chế, nhưng hy vọng điều này sẽ làm việc (tôi chỉ đăng vì nó đã được một thời gian kể từ khi bạn đăng câu hỏi):

>>> def toList(s): 
...  answer = [] 
...  L = s.split("&") 
...  for i in L: 
...    answer.append(tuple(i.split('='))) 
...  return answer 

>>> def toDict(L): 
...  answer = {} 
...  answer[L[0][0]] = L[0][1] 
...  for i in L[1:]: 
...    pk,sk = L[i][0].split('.') 
...    if pk not in answer: 
...      answer[pk] = [] 
...    if sk not in answer[pk][-1]: 
...      answer[pk][sk] = L[i][1] 
...    else: 
...      answer[pk].append({sk:L[i][1]}) 

Nếu điều này không phải là 100%, ít nhất cũng nên giúp bạn khởi đầu tốt.

Hope this helps

+0

Cảm ơn bạn đã phản hồi, nó đã cho tôi hiểu rõ hơn về một giới hạn mà tôi đã tạo ra bằng cách không làm cho Danh sách rõ ràng. Thật khó để biết khi nào nên tạo danh sách trừ khi được chỉ ra trong tên khóa. –

1

tôi thích một cách rõ ràng để giải quyết vấn đề của bạn:

  1. Divide các thành viên thuộc cùng cấu trúc (hoặc dict) vào một nhóm cùng với tên trường cùng, như

    'name=Kyle&phone1=1234&phone1=home&phone2=5678&phone2=work' 
    
  2. Trình tự của các trường trong các hình thức được đảm bảo, vì vậy multidict sẽ là: (('tên', 'Kyle'), ('Phone1', '123 4' , 'nhà'), ('Phone2', '5678', 'công việc'))

  3. Sau đó, mã sẽ như thế nào:

    def extract(key, values): 
        extractor = { 
         "name":str, 
         "phone":lambda *args:dict(zip(('number', 'type'), args) 
        } 
        trimed_key = re.match(r"^(\w+)", key).group(1) 
        return trimed_key, extractor(trimed_key, *values) 
    
    nested_dict = {} 
    for i in multidict(): 
        key, values = i[0], i[1:] 
        nested_dict.setdefault(key, []) 
        trimed_key, data_wanted = extract(key, values) 
        nested_dict[trimed_key].append(data_wanted) 
    
    for key in nested_dict: 
        if len(nested_dict[key]) == 1: 
         nested_dict[key] = nested_dict[key][0] 
    
+0

Cảm ơn bạn đã phản hồi. Rõ ràng là cách để giải quyết vấn đề này. Tôi đã kết thúc bằng cách sử dụng phương thức variable_decode() từ gói formencode như được đăng bởi Will. –

Các vấn đề liên quan