如何避免python词典中重复的if语句

时间:2011-09-22 07:44:04

标签: python dynamic dictionary if-statement repeat

我正在尝试用用户提交的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 个答案:

答案 0 :(得分: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')

答案 1 :(得分: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)