How to convert a MultiDict to nested dictionary

前端 未结 3 1559
不思量自难忘°
不思量自难忘° 2021-01-04 15:25

I would like to convert a POST from Webob MultiDict to nested dictionary. E.g.

So from a POST of:

\'name=Kyle&phone.number=1234&phone.type=ho         


        
相关标签:
3条回答
  • 2021-01-04 15:57

    I prefer an explicit way to solve your problem:

    1. Divide the members which belong to the same structure (or dict) into a same group with same field name, like

      'name=Kyle&phone1=1234&phone1=home&phone2=5678&phone2=work'
      
    2. The order of the fields in the form is guaranteed, so the multidict will be: (('name', 'Kyle'), ('phone1', '1234', 'home'), ('phone2', '5678', 'work'))

    3. Then the code will be like:

      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 讨论(0)
  • 2021-01-04 16:00

    If you have formencode installed or can install it, checkout out their variabledecode module

    0 讨论(0)
  • 2021-01-04 16:02

    I haven't had the time to test it and it's quite restrictive, but hopefully this will work (I'm only posting because it's been a while since you posted the question):

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

    If this is not 100%, it should at least get you on a good start.

    Hope this helps

    0 讨论(0)
提交回复
热议问题