Python如何实现itertools.product按元素自定义重复次数且低内存?
低内存实现方案
核心思路是避免生成重复排列再去重,直接通过选择元素放置位置的方式生成唯一结果,全程惰性迭代,内存占用为常数级,不受元素总量影响。
单元素指定次数场景(匹配你的需求示例)
你需要生成总长度为n、0出现k次、其余为1的序列,直接通过itertools.combinations选择0的放置位置即可:
import itertools def generate_target_seq(total_length: int, zero_count: int): # 遍历所有0的放置位置组合 for zero_pos in itertools.combinations(range(total_length), zero_count): res = [1] * total_length for pos in zero_pos: res[pos] = 0 yield tuple(res)
调用示例:
# 对应你的需求:总长度3,0出现1次 for item in generate_target_seq(3, 1): print(item) # 输出: # (0, 1, 1) # (1, 0, 1) # (1, 1, 0)
这个实现没有任何多余的内存开销,你可以边迭代边处理每个结果,哪怕总长度到上万级别也不会出现内存溢出。
通用多元素指定次数场景
如果你的业务需要支持多种元素各指定出现次数,可以用如下回溯实现的惰性生成器,同样全程不会生成重复结果,无需去重:
from typing import Any, Iterator def generate_unique_perm(element_count_map: dict[Any, int]) -> Iterator[tuple]: total_len = sum(element_count_map.values()) elems = list(element_count_map.keys()) counts = list(element_count_map.values()) def dfs(pos, remain_counts, current): if pos == total_len: yield tuple(current) return used = set() for idx, (e, cnt) in enumerate(zip(elems, remain_counts)): if cnt == 0 or e in used: continue used.add(e) remain_counts[idx] -= 1 current.append(e) yield from dfs(pos+1, remain_counts, current) current.pop() remain_counts[idx] += 1 yield from dfs(0, counts.copy(), [])
调用示例:
# 生成1个0、2个1的所有排列 list(generate_unique_perm({0:1, 1:2})) # 输出:[(0, 1, 1), (1, 0, 1), (1, 1, 0)]
内容的提问来源于stack exchange,提问作者Thomas Wagenaar
相关产品推荐
相关产品推荐

