如何将MultiDict转换为嵌套字典
我想把Webob中的POST请求从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',
},
有没有什么好主意?
编辑
我最后从formencode包中提取了variable_decode
方法,正如Will所提到的。唯一需要改变的是要明确列出列表,比如:
'name=Kyle&phone-1.number=1234&phone-1.type=home&phone-2.number=5678&phone-2.type=work'
这样做有很多好处。
3 个回答
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]})
如果这个不是百分之百的正确,至少能让你有个好的开端。
希望这对你有帮助。
1
我更喜欢一种明确的方法来解决你的问题:
把属于同一个结构(或者字典)的成员分到同一组,使用相同的字段名称,比如:
'name=Kyle&phone1=1234&phone1=home&phone2=5678&phone2=work'
表单中的字段顺序是有保证的,所以多重字典的格式会是: (('name', 'Kyle'), ('phone1', '1234', 'home'), ('phone2', '5678', 'work'))
然后代码会像这样:
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]
9
如果你已经安装了formencode,或者可以安装它的话,可以看看他们的 variabledecode模块。