2011-09-22 84 views
1

我想從用戶提交的html表單數據中創建一個新的字典。我最終編寫了重複的if語句,檢查xyz鍵是否在表單數據的字典中。我知道這是一個相當不理想的方法,雖然我不太清楚如何使用python實現這個。如何避免在python字典中重複if語句

這是表單數據字典:

form_data = { 
'urls': ['www.google.com', 'www.bing.com'], 
'useremail': ['[email protected]'], 
'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': ['[email protected]'], 
'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。另外,我不能處理用戶自己創建的任何字段,因爲我不知道該名稱。

長話短說:我怎樣才能使這個更高效和動態?

+0

請注意變量名的一致性('new_dic'是'cleared_data'等) – eumiro

回答

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

這是假設你只是想清理無論是實際提交。如果你正在尋找具體的東西,我建議列出需要查找的東西,然後遍歷列表並檢查東西是否在那裏。

form_data = { 
    'urls': ['www.google.com', 'www.bing.com'], 
    'useremail': ['[email protected]'], 
    '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': ['[email protected]'], 
'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)