【问题标题】:How to convert a MultiDict to nested dictionary如何将 MultiDict 转换为嵌套字典
【发布时间】:2012-01-30 00:52:05
【问题描述】:

我想将 Webob MultiDict 的 POST 转换为嵌套字典。例如

所以来自以下的 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',
  },

有什么想法吗?

编辑

我最终从 Will 发布的 formencode 包中提取了 variable_decode 方法。 唯一需要的更改是使列表明确,例如

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

出于多种原因,哪个更好。

【问题讨论】:

标签: python nested nested-forms webob


【解决方案1】:

如果您已安装或可以安装formencode,请查看他们的variabledecode module

【讨论】:

  • 我提取了 variable_decode() 方法,它可以正常工作,谢谢。
【解决方案2】:

我没有时间对其进行测试,而且限制性很大,但希望这会奏效(我只是发布,因为你发布问题已经有一段时间了):

>>> 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%,它至少应该让您有一个良好的开端。

希望对你有帮助

【讨论】:

  • 感谢您的回复,它让我更好地理解了我没有明确列出列表所造成的限制。除非在键名中指明,否则很难知道何时创建列表。
【解决方案3】:

我更喜欢用一种明确的方式来解决你的问题:

  1. 将属于同一结构(或dict)的成员划分为具有相同字段名称的同一组,例如

    'name=Kyle&phone1=1234&phone1=home&phone2=5678&phone2=work'
    
  2. 表单中字段的顺序是有保证的,所以 multidict 将是: (('name', 'Kyle'), ('phone1', '1234', 'home'), ('phone2', '5678', 'work'))

  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]
    

【讨论】:

  • 感谢您的回复。显式是解决这个问题的方法。我最终使用了 Will 发布的 formencode 包中的 variable_decode() 方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2020-09-03
  • 2013-12-07
  • 2019-12-09
  • 2019-10-10
  • 2021-05-18
相关资源
最近更新 更多