Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中使用递归组合可变大小的列表_Python_Loops_For Loop_Recursion_Iteration - Fatal编程技术网

在python中使用递归组合可变大小的列表

在python中使用递归组合可变大小的列表,python,loops,for-loop,recursion,iteration,Python,Loops,For Loop,Recursion,Iteration,我有一个问题,随着问题的发展,这个问题变得有点问题 情况: 我需要将大小可变的列表中的项目与大小可变的元素组合起来,存储这些组合,然后遍历它们。我尝试了itertools,但我得到了太多的组合,我不知道如何正确地“清洁”。 我通过创建与输入列表中“op”元素数量相同的for循环来获得正确的组合 例如: 注意:“op”字典的数量可能会有所不同!忽略这样的值,重要的是,我使用“op”字典列表基本上获得了名为NoOp节点的NukeGUI元素中的所有自定义控件。我需要迭代每个值的每个控件,以实现所有可能

我有一个问题,随着问题的发展,这个问题变得有点问题

情况:

我需要将大小可变的列表中的项目与大小可变的元素组合起来,存储这些组合,然后遍历它们。我尝试了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完成的
  • 在所有不同的op中使用此类列表的产品
  • 格式化和打印。3和4由
    打印组合处理


  • 或者,通过组合不同的运算指令,可以更紧凑地列出所有可能的组合:

    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']}