Python中带重复元素的元组求差(考虑重复次数)
解决方案
可以利用collections.Counter高效处理带重复元素的计数与减法逻辑,最后将结果转换为可哈希的元组,完全适配@lru_cache的键要求。
代码实现
from collections import Counter from functools import lru_cache def subtract_tuples(a: tuple, b: tuple) -> tuple: # 计算两个元组的元素计数差,仅保留a中剩余的元素及次数 remaining_counts = Counter(a) - Counter(b) # 将计数展开为元组(保证可哈希) return tuple(k for k, v in remaining_counts.items() for _ in range(v)) # 测试示例 print(subtract_tuples((1, 2, 3), (2, 3, 4))) # 输出 (1,) print(subtract_tuples((1, 2, 2, 3), (2, 3, 4))) # 输出 (1, 2) print(subtract_tuples((1, 2, 3), (2, 2, 3, 4))) # 输出 (1,) # 适配lru_cache的使用示例 @lru_cache(maxsize=None) def cached_process(a: tuple, b: tuple): result = subtract_tuples(a, b) return len(result) print(cached_process((1,2,2,3), (2,3,4))) # 输出 2
原理说明
Counter(a) - Counter(b)会自动计算元素的计数差:对每个元素,仅保留a中出现次数减去b中出现次数后仍为正的部分,次数为0或负数的元素会被直接丢弃。- 最终通过生成器表达式将计数展开为元组,元组是不可变类型,满足
@lru_cache对键的可哈希要求。 - 相比手动遍历计数,
Counter基于C语言实现,性能更优,代码也更简洁。
如果不想引入collections模块,也可以手动实现计数逻辑:
def subtract_tuples_manual(a: tuple, b: tuple) -> tuple: # 统计a中元素的出现次数 count_a = {} for num in a: count_a[num] = count_a.get(num, 0) + 1 # 统计b中元素的出现次数 count_b = {} for num in b: count_b[num] = count_b.get(num, 0) + 1 # 计算剩余元素并展开 remaining = [] for num, cnt in count_a.items(): diff = cnt - count_b.get(num, 0) if diff > 0: remaining.extend([num]*diff) return tuple(remaining)
不过手动实现的效率在处理大元组时会明显低于Counter方案。
内容的提问来源于stack exchange,提问作者rogerl
相关产品推荐
相关产品推荐

