要实现一个方法,验证参数中是否全部包含必填?
params = { "ImageId": '', "RegionId": '', "VSwitchId": '', "SecurityGroupId": '', "InstanceName": '', "InstanceType": '', "Amount": '', "InternetMaxBandwidthOut": '', # 1 mean with public, 0 mean no public } REQUIRED_FIELD = ["RegionId", "VSwitchId", "InstanceType", "SecurityGroupId"]
问题:REQUIRED_FIELD的字段必须都在params,在返回True,不在返回False?
我刚开始想到这个解决办法如下:
方法一:
def check_required_params(params):
return all([field in params.keys() for field in REQUIRED_FIELD])
测试通过,all()方法就是判断里面的一个迭代容器里面的元素都为True。
然后我再想还没有其他办法,搜索了一下网上资料,发现还有以下几种。
方法二:
def check_required_params(params):
return set(REQUIRED_FIELD).issubset(set(params.keys()))
这个方法挺pythonic,主要利用到了set.issubset方法,简单有效!
方法三:
def check_required_params(params):
#return set(params.keys()) & set(REQUIRED_FIELD) == set(REQUIRED_FIELD)
return set(params.keys()).intersection(set(REQUIRED_FIELD)) == set(REQUIRED_FIELD)
上面方法和注释到的意思是一样的,就是求两个set的交集,然后判断交集是否和必填项一样。
方法四:
def check_required_params(params):
return set(params.keys()) > set(REQUIRED_FIELD)
后来测试,我发现这种方法也能用,并且看起来很简单,那么我的疑问来了,我到底选择方法二还是方法四呢?
在代码看起来都很简洁的情况下,需要考虑性能,那么我需要测试一下,两个的性能谁更好?
1、10W的总集,20%的子集,
# 'check_required_params_withoperator' 0.03 sec
# 'check_required_params_withsubset' 0.02 sec
2、100W的总集,40%的子集
'check_required_params_withoperator' 0.68 sec
'check_required_params_withsubset' 0.54 sec
通过两个比较,数据量越大的时候,用issubset的效率更高,最后贴一下测试代码。
def measure_time(f):
def timed(*args, **kw):
import time
ts = time.time()
result = f(*args, **kw)
te = time.time()
print '%r %2.2f sec' % \
(f.__name__, te-ts)
return result
return timed
def create_test_simple(num=100, rate=0.2):
import random
def _create_one():
import string
return "".join(random.sample(string.ascii_letters, random.randint(5, 30)))
total_list = []
for i in range(num):
total_list.append(_create_one())
selected = random.sample(total_list, int(num * rate))
return total_list, selected
@measure_time
def check_required_params_withoperator(params, required_field):
return set(params) > set(required_field)
@measure_time
def check_required_params_withsubset(params, required_field):
return set(required_field).issubset(set(params))
if __name__ == '__main__':
total_list, selected = create_test_simple(100, 0.4)
print(check_required_params_withoperator(total_list, selected))
print(check_required_params_withsubset(total_list, selected))
最后我采用了set.issubset这种方法。
有其他更加简单,有效的办法,欢迎留言。