用Python如何检查一个列表是否为另一个列表的子集?

要实现一个方法,验证参数中是否全部包含必填? 

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这种方法。

有其他更加简单,有效的办法,欢迎留言。

 

 

你可能感兴趣的:(经验,数据结构,python)