如何生成嵌套层级问卷字典的所有选项组合?
层级式问卷选项全组合生成方案
问题分析
你遇到的核心问题是嵌套字典的层级遍历与组合生成:当字典中同时存在列表(叶子选项)和子字典(层级分类)时,普通的itertools.product无法直接处理嵌套结构,递归逻辑如果没区分叶子/非叶子节点,就会出现无限循环或类型错误。
解决思路
用递归函数遍历嵌套结构:
- 遇到列表类型:直接返回列表中的每个元素作为当前层级的选项
- 遇到字典类型:遍历字典的键值对,对每个值递归获取子层级的组合,再将当前键与子组合拼接
- 最终将所有层级的组合进行笛卡尔积运算,得到完整的选项路径
代码实现
示例嵌套问卷结构
先定义一个符合你场景的示例结构:
questionnaire = { "性别": ["男", "女"], "国家": { "亚洲": ["中国", "日本", "韩国"], "欧洲": ["德国", "法国"] }, "年龄": ["18-25", "26-35", "36+"] }
递归组合生成函数
from itertools import product def generate_combinations(data): # 处理叶子节点:直接返回每个元素的单元素列表(方便后续拼接) if isinstance(data, list): return [[item] for item in data] # 处理层级节点:递归获取子组合,再拼接当前键 elif isinstance(data, dict): level_combinations = [] for key, value in data.items(): sub_combs = generate_combinations(value) # 将当前层级的键与子组合拼接 for sub_comb in sub_combs: level_combinations.append([key] + sub_comb) return level_combinations # 非法类型处理 else: raise TypeError("仅支持字典或列表类型的嵌套结构") # 获取各维度的组合列表 gender_combs = generate_combinations(questionnaire["性别"]) country_combs = generate_combinations(questionnaire["国家"]) age_combs = generate_combinations(questionnaire["年龄"]) # 生成所有维度的笛卡尔积组合 all_combinations = [sum(comb, []) for comb in product(gender_combs, country_combs, age_combs)] # 输出结果 for idx, combo in enumerate(all_combinations, 1): print(f"组合{idx}: {combo}")
代码说明
- 递归函数逻辑:
- 当传入的是列表(比如性别选项),返回每个元素的单元素列表,比如
[["男"], ["女"]] - 当传入的是字典(比如国家分类),遍历每个大洲键,递归获取该大洲下的国家列表组合,再拼接大洲名称,比如
[["亚洲", "中国"], ["亚洲", "日本"], ...]
- 当传入的是列表(比如性别选项),返回每个元素的单元素列表,比如
- 笛卡尔积运算:用
itertools.product将性别、国家、年龄三个维度的组合两两配对,再拼接成完整路径 - 错误规避:通过类型判断区分叶子和层级节点,避免了
'str' object has no attribute 'values'这类类型错误;递归只处理字典和列表,不会陷入无限循环
运行结果示例
组合1: ['男', '亚洲', '中国', '18-25'] 组合2: ['男', '亚洲', '中国', '26-35'] 组合3: ['男', '亚洲', '中国', '36+'] 组合4: ['男', '亚洲', '日本', '18-25'] ... 组合24: ['女', '欧洲', '法国', '36+']
内容的提问来源于stack exchange,提问作者Francesco Perniola
相关产品推荐
相关产品推荐

