Python计算多维列表交集时如何保留对应重复频次的公共元素
问题说明
现有多维列表如下:
List_of_list=[[1,2,3,4,5,5], [1,2,3,5,5], [1,3,5,5]]
直接用集合交集方法计算所有内层列表的公共元素时,返回结果为[1,3,5],但元素5在所有内层列表中都重复出现2次,需要让交集结果保留2个5。
原因分析
Python原生set(集合)的交集逻辑只判断元素是否存在,不记录元素的出现次数,所以不管元素在原列表里重复多少次,交集中都只会保留1次,无法满足带重复计数的多重集交集需求。
解决方法
使用标准库collections.Counter实现即可。Counter专门用于统计可迭代对象的元素出现次数,且原生支持多重集交集运算:交集时会自动取每个元素在所有参与运算的Counter中的最小出现次数,完全匹配需求。
实现代码
from collections import Counter List_of_list = [[1,2,3,4,5,5], [1,2,3,5,5], [1,3,5,5]] # 用第一个内层列表初始化公共元素计数器 common_counts = Counter(List_of_list[0]) # 依次和剩余内层列表的计数器取交集 for sub_list in List_of_list[1:]: common_counts &= Counter(sub_list) # 将计数器按计数展开为普通列表 result = list(common_counts.elements()) print(result)
运行上述代码,输出结果为[1, 3, 5, 5],符合预期。
如果偏好更简洁的函数式写法,也可以用functools.reduce实现:
from collections import Counter from functools import reduce List_of_list = [[1,2,3,4,5,5], [1,2,3,5,5], [1,3,5,5]] common_counts = reduce(lambda x, y: x & y, (Counter(lst) for lst in List_of_list)) result = list(common_counts.elements())
逻辑说明
- 每个内层列表转为
Counter后,会存储类似{5:2, 1:1, 3:1}的键值对,键为列表元素,值为该元素的出现次数 Counter的&交集运算符会对每个公共元素,取所有计数器中该元素计数的最小值作为结果里的计数:如果某个元素在不同内层列表的出现次数不一致,结果中会保留出现次数最少的对应值,比如三个列表里5分别出现3、2、2次,结果里就会保留2个5- 最后通过
elements()方法,按照计数把元素重复对应次数,展开为普通列表
内容的提问来源于stack exchange,提问作者Pulkit yadav
相关产品推荐
相关产品推荐

