2012-01-30 24 views
10

POSTをWebob MultiDictからネストされた辞書に変換したいと思います。例えば。MultiDictをネストされた辞書に変換する方法

だから、のPOSTから:

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

multidictへ。

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

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

ネストされた辞書に任意のアイデア?

EDIT

私は意志によって投稿としてformencodeパッケージからvariable_decode方法を抽出することになりました。 必要な変更は、リストを明示的にすることです(例:

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

これは、多くの理由により優れています。

+0

またから胡椒を見てみましょうPylonsプロジェクト:http://docs.pylonsproject.org/projects/peppercorn/en/latest/フォームの作成中に明示的に指定する必要がありますが、任意のネストが可能です。 –

答えて

10

インストールしformencodeているか、それをインストールすることができた場合、それはだから、私はそれをテストする時間がなかったし、それはかなり限定的だが、うまくいけば、これは(私だけ掲示しています動作します彼らのvariabledecode module

+0

私はvariable_decode()メソッドを抽出し、それは、完全に、ありがとう、動作します。 –

1

をチェックアウトあなたが質問を投稿してからしばらくお待ちください):

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

これが100%ではない場合は、少なくともあなたのお手伝いが必要です。

ホープこれは

+0

あなたの応答をありがとう、それは私がListsを明示的にしないことによって作成した限界のより良い理解を与えました。リストを作成する時期をキー名で指定しない限り、それを知ることは難しいです。 –

1

は、私はあなたの問題を解決するために明示的な方法を好むことができます:

  1. 分割同じフィールド名と同じグループに同じ構造(または辞書)に所属するメンバー、

    'name=Kyle&phone1=1234&phone1=home&phone2=5678&phone2=work' 
    
  2. のような形でのフィールドの順序が保証されているので、multidictは次のようになります。 (( '名前'、 'カイル')、( 'のphone1'、「123 4' 、 '自宅')、( 'phone2の'、 '5678'、 '仕事'))

  3. その後、コードは次のようになります:

    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

ありがとうございます。明示的にこれを解決する方法です。私は、formencodeパッケージからvariable_decode()メソッドを使用して終了しました。 –

関連する問題