在python中使用递归组合可变大小的列表
我有一个问题,随着问题的发展,这个问题变得有点问题 情况: 我需要将大小可变的列表中的项目与大小可变的元素组合起来,存储这些组合,然后遍历它们。我尝试了itertools,但我得到了太多的组合,我不知道如何正确地“清洁”。 我通过创建与输入列表中“op”元素数量相同的for循环来获得正确的组合 例如: 注意:“op”字典的数量可能会有所不同!忽略这样的值,重要的是,我使用“op”字典列表基本上获得了名为NoOp节点的NukeGUI元素中的所有自定义控件。我需要迭代每个值的每个控件,以实现所有可能的组合:在python中使用递归组合可变大小的列表,python,loops,for-loop,recursion,iteration,Python,Loops,For Loop,Recursion,Iteration,我有一个问题,随着问题的发展,这个问题变得有点问题 情况: 我需要将大小可变的列表中的项目与大小可变的元素组合起来,存储这些组合,然后遍历它们。我尝试了itertools,但我得到了太多的组合,我不知道如何正确地“清洁”。 我通过创建与输入列表中“op”元素数量相同的for循环来获得正确的组合 例如: 注意:“op”字典的数量可能会有所不同!忽略这样的值,重要的是,我使用“op”字典列表基本上获得了名为NoOp节点的NukeGUI元素中的所有自定义控件。我需要迭代每个值的每个控件,以实现所有可能
for option1 in op1["options"]:
for option2 in op2["options"]:
for option3 in op3["options"]:
print op1["control"], option1, op2["control"], option2, op3["control"], option3
现在我只是想弄清楚如何定义基本情况:/
def getCombos(controls, n = 0):
#combos = []
if n == 0:
#return [(control["control"], option) for control in controls for option in control["options"]]
return [(item["control"], option) for item in controls for option in item["options"]]
else:
for control in controls:
return(getCombos(controls, n-1))
n -= 1
op1 = {"control": "Material", "options": ["Glass", "Metal", "Wood"]}
op2 = {"control": "Base",
"options": ["Chrome", "Brass", "Bronce", "Gold", "Nickel", "Red Gold"]}
op3 = {"control": "Color", "options": ["Red", "Blue", "Green", "Cyan", "SomeWonderfulNewColor"]}
controls = [op1, op2, op3]
#NOTE: number of elements (dict) in list controls may vary!
for i,combo in enumerate(getCombos(controls, n=len(controls))):
print i, combo
这个脚本只是递归地打印控件
在这种情况下,我如何使用递归,更重要的是,我是否应该使用递归,如果是,我如何处理这种情况并将其分解为组件?
干杯,不是100%确定你想要实现什么,但是如果你想获得所有选项的组合,你应该使用: 如果您想将它们与相应的
控件
组合,可以编写一个helper函数来获取这些对,然后获取这些对的产品
:
>>> pairs = lambda op: [(op["control"], o) for o in op["options"]]
>>> pairs(op1)
[('Material', 'Glass'), ('Material', 'Metal'), ('Material', 'Wood')]
>>> list(itertools.product(*map(pairs, (op1, op2, op3))))
[(('Material', 'Glass'), ('Base', 'Chrome'), ('Color', 'Red')),
(('Material', 'Glass'), ('Base', 'Chrome'), ('Color', 'Blue')),
(('Material', 'Glass'), ('Base', 'Chrome'), ('Color', 'Green')),
...
(('Material', 'Wood'), ('Base', 'Red Gold'), ('Color', 'Cyan')),
(('Material', 'Wood'), ('Base', 'Red Gold'), ('Color', 'SomeWonderfulNewColor'))]
绝对应该使用递归:
def print_all(controls, idx, combination):
if idx == len(controls):
print(combination)
return
for x in controls[idx]['options']:
print_all(controls, idx+1, combination + " " + controls[idx]['control'] + " " + str(x))
op1 = {"control": "Material", "options": ["Glass", "Metal", "Wood"]}
op2 = {"control": "Base",
"options": ["Chrome", "Brass", "Bronce", "Gold", "Nickel", "Red Gold"]}
op3 = {"control": "Color", "options": ["Red", "Blue", "Green", "Cyan", "SomeWonderfulNewColor"]}
op4 = {"control": "year", "options": [2010, 2020]}
controls = [op1, op2, op3, op4]
print_all(controls, 0, "")
以下是一种通过三个步骤打印所有组合的方法:
{control:control\u val,options:options\u vals}
转到{control\u val:options\u vals}
。这是通过from_record
功能完成的{control\u val:options\u val}
转换为[(control\u val,options\u val)]
列表。这是由iter dict完成的打印组合处理
或者,通过组合不同的运算指令,可以更紧凑地列出所有可能的组合:
res = dict()
ops = [op1, op2, op3]
for op in ops:
res.update(from_record(op))
# {'Base': ['Chrome', 'Brass', 'Bronce', 'Gold', 'Nickel', 'Red Gold'],
# 'Color': ['Red', 'Blue', 'Green', 'Cyan', 'SomeWonderfulNewColor'],
# 'Material': ['Glass', 'Metal', 'Wood']}
虽然我喜欢这篇介绍,但这篇文章缺乏具体的样本数据。您当前方法的输入、预期输出和错误输出。您想要哪种“组合”?您是否尝试过
itertools.product(opt1[“options”]、opt2[“options”]、…)
?也许我真的应该在前面的示例中放入元组:op1[“options”]:op2[“options”]:op3[“options”]:打印(op1[“control”]、option1),(op2[“control”]、option2),(op3[“control”]、option3)我将尝试已经发布的解决方案,将代码保存在文件中,更正缩进并运行它。这个解决方案对我来说非常优雅,我如何将输出从字符串更改为成对,并将其存储在列表中以供进一步使用?@Klemen你能告诉我这些成对是什么样的吗?('Material'、'Glass')、('Base'、'Chrome'),(‘颜色’、‘红色’)、(‘材料’、‘玻璃’、(‘基础’、‘铬’)、(‘颜色’、‘蓝色’)、(‘材料’、‘玻璃’)、(‘基础’、‘铬’、(‘颜色’、‘绿色’)、。。(‘材料’、‘木材’、(‘底座’、‘红金’、(‘颜色’、‘青色’)、(‘材料’、‘红金’、(‘底座’、‘红金’)、(‘颜色’、‘新颜色’)、[(‘材料’、‘木材’、(‘底座’、‘红金’)、(‘颜色’、‘蓝色’、(‘年份’、‘2010’)、[‘材料’、‘木材’),('Base'、'Red Gold')、('Color'、'Blue')、('year'、'2020')]?有道理。你可能应该在问题中添加一个你想要的例子。
from itertools import product
def from_record(dct):
return {dct["control"]: dct["options"]}
def iter_dict(dct):
yield from ((k, v) for k, vs in dct.items() for v in vs)
def print_combinations(dcts):
for item in product(*(iter_dict(from_record(dct)) for dct in dcts)):
print(", ".join(["{}: {}".format(*t) for t in item]))
op1 = {"control": "Material", "options": ["Glass", "Metal", "Wood"]}
op2 = {
"control": "Base",
"options": ["Chrome", "Brass", "Bronce", "Gold", "Nickel", "Red Gold"],
}
op3 = {
"control": "Color",
"options": ["Red", "Blue", "Green", "Cyan", "SomeWonderfulNewColor"],
}
print_combinations([op1, op2, op3])
# e.g.
# Material: Glass, Base: Chrome, Color: Red
# Material: Glass, Base: Chrome, Color: Blue
# Material: Glass, Base: Chrome, Color: Green
# Material: Glass, Base: Chrome, Color: Cyan
# Material: Glass, Base: Chrome, Color: SomeWonderfulNewColor
res = dict()
ops = [op1, op2, op3]
for op in ops:
res.update(from_record(op))
# {'Base': ['Chrome', 'Brass', 'Bronce', 'Gold', 'Nickel', 'Red Gold'],
# 'Color': ['Red', 'Blue', 'Green', 'Cyan', 'SomeWonderfulNewColor'],
# 'Material': ['Glass', 'Metal', 'Wood']}