如何修改Python生成器,限时生成两列表的唯一随机组合
问题描述
我有两个列表:
a = [1, 2, 3, 5] b = ["a", "b", "c", "d"]
我想用Python生成器生成所有可能的组合。我知道可以这么做:
combinations = list(itertools.product(a,b)) random.shuffle(combinations)
但这种方法内存开销极大——哪怕我只需要两个随机唯一组合,也得把所有可能的组合都存在内存里。
我的目标是实现一个Python生成器,内存开销随请求迭代次数线性增长,最大迭代次数时的开销和itertools的方法一致。
我目前写了这段代码:
from typing import List import random def _unique_combinations(a: List, b: List): """ Creates a generator that yields unique combinations of elements from a and b in the form of (a_element, b_element) tuples in a random order. """ len_a, len_b = len(a), len(b) generated = set() for i in range(len_a): for j in range(len_b): while True: # choose random elements from a and b element_a = random.choice(a) element_b = random.choice(b) if (element_a, element_b) not in generated: generated.add((element_a, element_b)) yield (element_a, element_b) break
但这段代码有个缺陷:如果random.choice的运气太差,理论上可能无限循环。
我希望修改这个生成器,让它能在固定时间内生成随机索引,同时跟踪这些索引,保证内存开销线性增长而非指数增长。该怎么修改?
改进方案
可以通过限制随机尝试次数+兜底遍历的方式解决无限循环问题,同时保持内存开销线性增长。核心逻辑如下:
- 用集合跟踪已生成的组合索引(用索引而非元素,适配列表含重复元素的场景)
- 优先尝试有限次数的随机索引生成,多次失败后直接遍历剩余索引,确保不会卡住
修改后的代码:
from typing import List import random def random_unique_combinations(a: List, b: List): """ 生成器,以随机顺序返回a和b元素的唯一组合,内存开销随迭代次数线性增长 """ len_a, len_b = len(a), len(b) total_combinations = len_a * len_b used_indices = set() max_random_attempts = 10 # 设定最大随机尝试次数,避免无限循环 while len(used_indices) < total_combinations: # 先尝试随机生成未使用的索引 for _ in range(max_random_attempts): i = random.randint(0, len_a - 1) j = random.randint(0, len_b - 1) if (i, j) not in used_indices: used_indices.add((i, j)) yield (a[i], b[j]) break else: # 多次随机尝试失败,兜底遍历剩余索引 for i in range(len_a): for j in range(len_b): if (i, j) not in used_indices: used_indices.add((i, j)) yield (a[i], b[j]) break else: continue # 内层循环没找到,继续外层循环 break # 找到后跳出外层循环
方案优势
- 彻底避免无限循环:设置了
max_random_attempts,当连续随机命中已用索引时,直接切换到遍历模式,确保能获取到未使用的组合。 - 内存线性增长:
used_indices集合的大小随迭代次数增加,最多存储total_combinations个索引元组,内存开销和生成所有组合的方式一致(甚至更小)。 - 随机性有保障:大部分场景下优先用随机生成,仅在随机效率极低时才用遍历,既保证了随机顺序,又不会出现性能问题。
内容的提问来源于stack exchange,提问作者eljiwo
相关产品推荐
相关产品推荐

