如何避免在Python字典中重复的if语句
我正在尝试根据用户提交的HTML表单数据创建一个新的字典。结果我写了很多重复的if语句,检查某个键(比如xyz)是否在表单数据的字典里。我知道这样做效率不高,但我不太确定该如何用Python来实现。
这是表单数据的字典:
form_data = {
'urls': ['www.google.com', 'www.bing.com'],
'useremail': ['my@email.com'],
'emailfield': ['1'],
'addressfield': ['1'],
'addressfield_info':['Company'],
'addressfield_instruction': ['Please only if the company is a LLC'],
'phonefield': ['1'],
'phonefield_instruction': ['please include area code']
}
我想创建一个看起来像这样的字典:
new_dic = {
'urls': ['www.google.com', 'www.bing.com'],
'useremail': ['my@email.com'],
'infofield': [
{'field': 'email'},
{'field': 'address', 'info':'Company', 'instruction': 'Please only if the company is a LLC'},
{'field':'phone', 'instruction': 'please include area code'}
]
}
重要提示:'xyzfield'是必须的,而'xyzfield_info'和'xyzfield_instruction'都是可选的。此外:用户可以添加更多字段,比如'agefield'、'agefield_info'和'agefield_instruction'。
我遇到的问题是如何高效地检查xyzfield(比如邮箱、电话等)是否在字典里。如果在的话,还要检查可选字段是否也在。这目前的做法大概是这样的:
if 'emailfield' in form_data:
infofield = {'field': 'email'}
if 'emailfield_info' in form_data:
infofield['info'] = form_data['emailfield_info']
if 'emailfield_instruction' in form_data:
infofield['instruction'] = form_data['emailfield_instruction']
cleaned_data['infofields'].append(infofield)
...
而且我对每个字段都这样做,所以我有4到5个类似的代码。此外,我也无法处理用户自己创建的字段,因为我事先不知道它们的名字。
总之:我该如何让这个过程更高效和灵活呢?
2 个回答
1
这段话的意思是,假设你只是想清理那些实际提交的内容。如果你想要确保某些特定的东西存在,我建议你先列出一个要检查的清单,然后逐个检查这些东西是否存在。
form_data = {
'urls': ['www.google.com', 'www.bing.com'],
'useremail': ['my@email.com'],
'emailfield': ['1'],
'addressfield': ['1'],
'addressfield_info':['Company'],
'addressfield_instruction': ['Please only if the company is a LLC'],
'phonefield': ['1'],
'phonefield_instruction': ['please include area code']
}
def make_field_dict(form_data, base):
field_dict = {}
name_field = base + "field"
name_info = base + "field_info"
name_inst = base + "field_instruction"
if name_field not in form_data:
raise KeyError, "%s not found in form_data" % name_field
if form_data[name_field] != ['1']:
raise ValueError, "%s not valid in form_data" % name_field
field_dict["field"] = base
if name_info in form_data:
lst = form_data[name_info]
if len(lst) != 1:
raise ValueError, "%s not valid in form_data" % name_info
field_dict["info"] = lst[0]
if name_inst in form_data:
lst = form_data[name_inst]
if len(lst) != 1:
raise ValueError, "%s not valid in form_data" % name_inst
field_dict["instruction"] = lst[0]
return field_dict
def parse_form_data(form_data):
cleaned_data = {}
cleaned_data["infofield"] = []
seen = set()
for key, value in form_data.items():
if "field" not in key:
cleaned_data[key] = value
else:
base, _, tail = key.partition("field")
if base in seen:
continue
cleaned_data["infofield"].append(make_field_dict(form_data, base))
seen.add(base)
return cleaned_data
new_dic = {
'urls': ['www.google.com', 'www.bing.com'],
'useremail': ['my@email.com'],
'infofield': [
{'field': 'email'},
{'field': 'address', 'info':'Company', 'instruction': 'Please only if the company is a LLC'},
{'field':'phone', 'instruction': 'please include area code'}
]
}
clean_data = parse_form_data(form_data)
new_dic['infofield'].sort()
clean_data['infofield'].sort()
assert(new_dic == clean_data)
4
避免重复代码的标准方法在这里也适用——把重复的代码提取到一个函数里:
def extract_field(form_data, clean, fieldname, optional=('info', 'instruction')):
if fieldname+'field' in form_data:
infofield = { 'field': fieldname }
for opt in optional:
optname = '{}field_{}'.format(fieldname, opt)
if optname in form_data:
infofield[opt] = form_data[optname]
clean.append(infofield)
extract_field(form_data, cleaned_data['infofields'], 'email')
extract_field(form_data, cleaned_data['infofields'], 'address')
extract_field(form_data, cleaned_data['infofields'], 'phone')