如何为Python嵌套列表元素设置抽取概率并生成不重复组合
问题核心修正与实现方案
首先你原来对random.choices()的用法有误,这个函数的作用是从单个一维列表中按权重抽取指定数量的元素,不能直接传入嵌套的layers和权重列表,需要针对每个子列表(也就是每个图片层)单独执行带权重抽取。
实现思路
- 每个层单独调用
random.choices(),传入对应层的素材列表和该层的权重配置,单次抽取1个元素 - 用集合存储已经生成过的组合(需要把列表转成可哈希的元组才能存入集合),避免重复
- 循环生成直到凑够你需要的组合数量,或者穷尽所有可能的组合(总共有44433*3=1728种不重复组合,数量很小,不会有性能问题)
完整可运行代码
import random from pathlib import Path # 加载各层素材,和你原来的逻辑一致 layers = [list(Path(directory).glob("*.png")) for directory in ("dir1/", "dir2/", "dir3/", "dir4/", "dir5/", "dir6/")] # 各层对应的抽取权重 list_of_prob = [ [0.6, 0.3, 0.075, 0.025], [0.6, 0.3, 0.075, 0.025], [0.6, 0.3, 0.075, 0.025], [0.55, 0.35, 0.1], [0.55, 0.35, 0.1], [0.55, 0.35, 0.1] ] # 你要生成的不重复组合数量,不要超过1728的总上限 TARGET_COUNT = 100 generated = set() result = [] while len(result) < TARGET_COUNT: # 每层按对应权重抽1个元素,choices返回的是列表,取第0个即可 current_combo = tuple(random.choices(layer, weights=prob, k=1)[0] for layer, prob in zip(layers, list_of_prob)) # 检查是否已经生成过 if current_combo not in generated: generated.add(current_combo) # 转成列表存入结果,符合你需要的格式 result.append(list(current_combo)) # 最终result就是你要的newList print(result)
补充说明
random.choices()的k参数代表你要从当前传入的列表里抽多少个元素,这里我们每次从单个层只抽1个,所以k固定为1- 如果需要生成的组合数量接近1728的总上限,为了避免循环次数过多,可以先计算所有可能组合的权重乘积,再按权重采样不重复的组合,不过常规批量生成图片的场景下上面的循环方案足够使用
内容的提问来源于stack exchange,提问作者Dominick Fiducia
相关产品推荐
相关产品推荐

