如何高效生成元素仅含正负其一的可迭代对象幂集?
问题描述
我希望找到一种简单方法,生成可迭代对象的幂集,要求每个元素只能取其本身或相反数,同一组合中不能同时包含某元素及其相反数。原可迭代对象无重复元素,组合顺序无关。
示例
可迭代对象:
elements = [-2, 1]
期望生成的幂集:
[] [-2] [2] [-1] [1] [-2, -1] [-2, 1] [2, -1] [2, 1]
需要排除的子集:
[-1, 1] [-2, 2]
我当前的做法是将原元素列表与[-x for x in elements]组合后,使用现有幂集实现生成幂集,再过滤掉不符合要求的组合,但这种方式不够高效。请问是否存在无需事后过滤的简便解决方案?
解决方案
核心思路是直接针对每个元素生成合法选项,从根源避免无效组合,无需事后过滤。每个元素有三种互斥选择:不包含它、包含它本身、包含它的相反数,所有合法子集就是这些选项的组合结果。
方法1:递归实现
def signed_power_set(elements): if not elements: yield [] return current = elements[0] # 递归处理剩余元素的所有合法子集 for subset in signed_power_set(elements[1:]): yield subset # 不选当前元素 yield subset + [current] # 选当前元素本身 yield subset + [-current] # 选当前元素的相反数
方法2:迭代器组合(基于itertools.product)
import itertools def signed_power_set(elements): # 为每个元素生成三个选项:空(不选)、本身、相反数 options = [[], [x], [-x] for x in elements] # 生成所有选项的笛卡尔积,合并每个组合中的子列表得到最终子集 for parts in itertools.product(*options): result = [] for part in parts: result.extend(part) yield result
验证效果
调用函数测试示例输入:
elements = [-2, 1] for subset in signed_power_set(elements): print(subset)
输出结果(顺序可能略有不同,但均为合法子集):
[] [-2] [2] [-1] [-2, -1] [-2, 1] [2, -1] [2, 1] [1]
两种方法都不会生成包含元素及其相反数的无效子集,效率远高于“先生成所有可能再过滤”的方案。
内容的提问来源于stack exchange,提问作者upe
相关产品推荐
相关产品推荐

