求类似is_subset()的列表包含判断函数:统计重复项且不超量
实现考虑元素出现次数的列表子集判断函数
普通的集合issubset()方法会忽略元素的重复次数,而用all(item in main_list for item in test_list)又会误判重复元素超标的情况。要解决这个问题,我们可以借助collections.Counter来统计元素的出现频次,以此判断测试列表是否满足“所有元素的出现次数不超过主列表对应次数”的要求。
实现方案
使用Counter统计两个列表的元素频次,有两种简洁的判断方式:
方式一:遍历频次字典验证
from collections import Counter def is_multiset_subset(main_list, test_list): main_counts = Counter(main_list) test_counts = Counter(test_list) # 检查测试列表中每个元素的频次都不超过主列表的对应频次 return all(test_counts[elem] <= main_counts.get(elem, 0) for elem in test_counts)
方式二:利用Counter的减法特性
Counter支持减法操作,会保留测试列表中主列表没有或频次超过主列表的元素。如果减法结果为空,说明测试列表是符合要求的子集:
from collections import Counter def is_multiset_subset(main_list, test_list): main_counts = Counter(main_list) test_counts = Counter(test_list) # 减法结果为空则说明所有元素频次都符合要求 return len(test_counts - main_counts) == 0
测试示例
用给出的案例验证:
MainList = [1, 2, 5, 3, 2, 7, 3, 3, 8, 1] print(is_multiset_subset(MainList, [1, 2, 3])) # 返回True print(is_multiset_subset(MainList, [3, 3, 3, 1])) # 返回True print(is_multiset_subset(MainList, [1, 3, 4, 5])) # 返回False:4不在主列表中 print(is_multiset_subset(MainList, [1, 2, 1, 2, 2, 3])) # 返回False:2的数量过多 print(is_multiset_subset(MainList, [5, 3, 1, 8])) # 返回True:无需考虑顺序 print(is_multiset_subset(MainList, [5, 5, 5, 5])) # 返回False:5的数量超标
说明
这两种方法都无需手动逐元素遍历比较,时间复杂度为O(n+m)(n、m分别为主列表和测试列表的长度),效率远高于手动计数实现,且代码简洁易读。
内容的提问来源于stack exchange,提问作者Eric Snyder
相关产品推荐
相关产品推荐

