You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为数组长度设置权重并生成可变列数的特征数组

问题描述

我一直搞不定怎么给数组长度设置权重,想让数组里的特定列按概率出现,生成不同长度的结果。

当前输出

# Output 1
['green eyes', 'black hair', 'girl', 'human', 'happy', 'propeller beanie', 'kitsune mask', 'smurk', 'horns', 'monocle', 'wings', 'halo', [...]]
# Output 2
['brown eyes', 'brown hair', 'boy', 'human', 'tired', 'propeller beanie', 'oni mask', 'frowning', 'cat ears', 'tail', 'bat wings', 'halo', [...]]

目标输出示例

# Output1
['green eyes', 'black hair', 'girl', 'happy', 'smurk']
# Output2
['green eyes', 'black hair', 'girl', 'elf', 'sad', 'horns', 'wings']
# Output3
['green eyes', 'black hair', 'girl', 'kitsune mask']

核心需求

输出元素来自不同加权列表,比如:

feeling = ["tired", "happy", "sad", "grumpy"]
  • 前3列(眼睛颜色、头发颜色、性别)必须出现(100%概率)
  • 第4列及以后的特征(种族、情绪、头饰等)各自有独立的出现概率:种族22%、情绪18%、头饰12%、面饰9%、表情15%、杂项10%、配饰7%、翅膀6%、神性1%
  • 以情绪为例:18%概率出现该列,且出现时"happy"的选中概率是32%

之前尝试把数组截到前2列,再用random.choices给后续列加权合并,但每次只能取单个值,迭代会导致重复元素,没成功生成可变长度的输出。

当前代码

import random
import math
import os

# 假设这些列表已提前定义
modelSex = ["girl", "boy"]
race = ["human", "elf", "dwarf", "orc", "halfling", "gnome", "tiefling"]
feeling = ["tired", "happy", "sad", "grumpy"]
hairColor = ["black", "brown", "blonde", "red", "auburn", "white", "gray", "blue", "green", "purple", "pink", "silver", "gold", "orange"]
eyeColor = ["green", "brown", "blue", "hazel", "amber", "gray", "violet", "red", "gold", "silver", "pink", "black", "orange", "yellow"]
headWear = ["propeller beanie", "cap", "hat", "helmet", "bandana", "tiara", "crown", "headband", "hood"]
faceWear = ["kitsune mask", "oni mask", "sunglasses", "monocle", "eyepatch"]
expression = ["smirk", "frowning", "neutral"]
misc = ["horns", "cat ears", "tail"]
classy = ["monocle", "top hat", "cane", "gloves"]
wings = ["wings", "bat wings", "dragon wings"]
divine = ["halo"]

modelSexOdds = random.choices(modelSex, weights=(50, 50))  # always
raceOdds = random.choices(race, weights=(6, 10, 3, 9, 60, 5, 7))
feelingOdds = random.choices(feeling, weights=(15, 32, 29, 24))
hairOdds = random.choices(
    hairColor, weights=(13, 8, 12, 11, 5, 7, 10, 8, 6, 5, 8, 4, 2, 1)
)
eyeOdds = random.choices(
    eyeColor, weights=(13, 8, 12, 11, 5, 7, 10, 8, 6, 5, 8, 4, 2, 1)
)
headWearOdds = random.choices(headWear, weights=(27, 14, 13, 15, 10, 7, 5, 2, 7))
faceWearOdds = random.choices(faceWear, weights=(5, 20, 23, 35, 17))
expressionOdds = random.choices(expression, weights=(15, 47, 38))
miscOdds = random.choices(misc, weights=(30, 40, 10))
classyOdds = random.choices(classy, weights=(25, 8, 36, 31))
wingsOdds = random.choices(wings, weights=(37, 26, 37))

traits = [
    "Eye Color",
    "Hair Color",
    "Sex",
    "Race",
    "Feeling",
    "Head Wear",
    "Face Wear",
    "Expression",
    "Misc",
    "Classy",
    "Wings",
    "Divine",
]

trait_options = {
    trait_name: [
        os.path.splitext(x)[0]
        for x in os.listdir("scripts/Prompts/assets/" + trait_name)
    ]
    for trait_name in traits
    if trait_name != "modelSex"
}
trait_options["Eye Color"] = eyeOdds
trait_options["Hair Color"] = hairOdds
trait_options["Sex"] = modelSexOdds
trait_options["Race"] = raceOdds
trait_options["Feeling"] = feelingOdds
trait_options["Head Wear"] = headWearOdds
trait_options["Face Wear"] = faceWearOdds
trait_options["Expression"] = expressionOdds
trait_options["Misc"] = miscOdds
trait_options["Classy"] = classyOdds
trait_options["Wings"] = wingsOdds
trait_options["Divine"] = divine


max_possible_combinations = math.prod([len(trait_options[t]) for t in trait_options])

# eyeColor, 0 | 100%
# hairColor, 1 | 100%
# modelSex, 2 | 100%
# raceOdds, 3 | 22%
# feelingOdds, 4 | 18%
# headWearOdds, 5 | 12%
# faceWearOdds, 6 | 9%
# expressionOdds, 7 | 15%
# miscOdds, 8 | 10%
# classyOdds, 9 | 7%
# wingsOdds, 10 | 6%
# divineOdds, 11 | 1%
traitsOdds = [
    raceOdds,
    feelingOdds,
    headWearOdds,
    faceWearOdds,
    expressionOdds,
    miscOdds,
    classyOdds,
    wingsOdds,
    divine,
]

allOdds = random.choices(traitsOdds, weights=(22, 18, 12, 9, 15, 10, 7, 6, 1))
print(allOdds)
dnas = []

for i in range(2):
    dna = {}
    for t in traits:
        dna[t] = trait_options[t][random.randint(0, len(trait_options[t]) - 1)]
    dnas.append(dna)

for dna in dnas:
    text_config = []
    for trait_name, trait_value in dna.items():
        if trait_name == "modeSexx":
            pass
        else:
            text_config.append(f"{trait_value}")
    text_config.append(text_config)
print(text_config)
解决方案

核心思路是:先固定必选特征,再对可选特征逐个判断是否保留,同时处理每个特征内部的加权选择。

优化后的代码

import random
import os

# 定义所有特征列表及权重
# 必选特征(100%出现)
mandatory_traits = [
    ("Eye Color", eyeColor, (13, 8, 12, 11, 5, 7, 10, 8, 6, 5, 8, 4, 2, 1)),
    ("Hair Color", hairColor, (13, 8, 12, 11, 5, 7, 10, 8, 6, 5, 8, 4, 2, 1)),
    ("Sex", modelSex, (50, 50))
]

# 可选特征(带出现概率+内部元素权重)
optional_traits = [
    ("Race", race, (6, 10, 3, 9, 60, 5, 7), 22),
    ("Feeling", feeling, (15, 32, 29, 24), 18),
    ("Head Wear", headWear, (27, 14, 13, 15, 10, 7, 5, 2, 7), 12),
    ("Face Wear", faceWear, (5, 20, 23, 35, 17), 9),
    ("Expression", expression, (15, 47, 38), 15),
    ("Misc", misc, (30, 40, 10), 10),
    ("Classy", classy, (25, 8, 36, 31), 7),
    ("Wings", wings, (37, 26, 37), 6),
    ("Divine", divine, (100,), 1)  # 神性只有一个元素,权重设为100%
]

def generate_trait_list():
    trait_list = []
    
    # 添加必选特征
    for name, options, weights in mandatory_traits:
        # 从选项中加权选择一个元素
        selected = random.choices(options, weights=weights)[0]
        trait_list.append(selected)
    
    # 处理可选特征:逐个判断是否保留
    for name, options, weights, appearance_prob in optional_traits:
        # 按概率决定是否添加该特征
        if random.randint(1, 100) <= appearance_prob:
            selected = random.choices(options, weights=weights)[0]
            trait_list.append(selected)
    
    return trait_list

# 生成3个示例输出
for i in range(3):
    result = generate_trait_list()
    print(f"# Output{i+1}")
    print(result)

代码说明

  1. 拆分特征类型:把特征分成必选和可选两类,必选直接全部添加,可选则按设定的概率判断是否加入结果。
  2. 双层权重处理:
    • 第一层:对每个可选特征,用random.randint(1,100)判断是否满足出现概率(比如18%概率就判断随机数≤18)。
    • 第二层:若特征被选中,再用random.choices按内部权重选取具体元素(比如情绪里"happy"占32%)。
  3. 避免重复元素:每个特征只处理一次,不会重复添加,解决了之前迭代导致重复的问题。
  4. 结构清晰:把特征配置集中管理,后续调整概率或选项更方便。

内容的提问来源于stack exchange,提问作者Norepi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:35:18