如何统计列表的列表中匹配特定列表的三类情况出现次数?
问题分析
你需要统计列表b中满足以下三类情况的子列表次数:
- 和
a完全相同的列表 - 元素和
a一致但顺序不同的列表 - 包含
a所有元素且元素数量多于a的列表
这三类的核心共同点是:子列表包含a的所有元素(不管顺序,也不管是否有额外元素)。你之前用字符串包含的方法行不通,因为列表转字符串后完全依赖元素的顺序和拼接格式,一旦顺序变化或者插入新元素,字符串匹配就会失效。
解决方案
根据a中元素是否有重复,我们有两种高效的实现方式:
情况1:a中的元素都是唯一的
这种场景下,用集合子集判断是最简单高效的方法:
a = ['Bananas', 'Ananas', 'Peach', 'Grapes', 'Oranges'] b = [['Bananas', 'Ananas', 'Peach', 'Grapes', 'Oranges'], ['Bananas', 'Ananas', 'Peach', 'Grapes', 'Oranges', 'Pear', 'Apple'], ['Oranges', 'Strawberry', 'Pear'], ['Peach', 'Bananas', 'Ananas', 'Grapes', 'Oranges'], # 顺序不同的符合项 ['Grapes', 'Peach']] # 缺少元素的不符合项 count_matches = 0 a_set = set(a) # 转成集合后自动忽略顺序和重复元素 for sublist in b: sublist_set = set(sublist) # 判断a的所有元素都存在于子列表中(子集关系) if a_set.issubset(sublist_set): count_matches += 1 print(count_matches) # 输出:3(对应第1、2、3类的子列表)
情况2:a中存在重复元素(通用场景)
如果a里有重复元素(比如a = ['Apple', 'Apple', 'Banana']),集合去重的方法就会失效,这时候需要用collections.Counter来统计元素的出现次数,确保子列表中每个元素的数量都不少于a中的数量:
from collections import Counter a = ['Bananas', 'Ananas', 'Peach', 'Grapes', 'Oranges'] b = [['Bananas', 'Ananas', 'Peach', 'Grapes', 'Oranges'], ['Bananas', 'Ananas', 'Peach', 'Grapes', 'Oranges', 'Pear', 'Apple'], ['Oranges', 'Strawberry', 'Pear'], ['Peach', 'Bananas', 'Ananas', 'Grapes', 'Oranges'], ['Grapes', 'Peach']] count_matches = 0 a_counter = Counter(a) # 统计a中每个元素的出现次数 for sublist in b: sublist_counter = Counter(sublist) # 逐一检查a中元素的出现次数是否都被子列表满足 is_valid = True for elem, required_count in a_counter.items(): if sublist_counter.get(elem, 0) < required_count: is_valid = False break if is_valid: count_matches += 1 print(count_matches) # 同样输出:3
为什么你的原代码不行?
你把列表转成字符串后用gg in ff判断,本质是依赖列表的字符串拼接顺序。比如a转成字符串是"Bananas', 'Ananas', 'Peach', 'Grapes', 'Oranges",而顺序调换后的子列表转成字符串是"Peach', 'Bananas', 'Ananas', 'Grapes', 'Oranges",这时候前者不在后者中,就会被错误地排除。这种方法完全不可靠,绝对不建议用来判断列表元素的包含关系。
内容的提问来源于stack exchange,提问作者Tiago Peres
相关产品推荐
相关产品推荐

