在python中使用递归来组合可变大小的列表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在python中使用递归来组合可变大小的列表相关的知识,希望对你有一定的参考价值。
我有一个问题的问题,随着问题的出现会产生一些问题。
情况:
我需要将可变大小的列表中的项目与可变大小的元素组合在一起,存储这些组合,然后迭代它们。我尝试过itertools,但是我得到了太多的组合,我不知道如何正确地“清理”。我通过创建与输入列表中“op”元素的数量一样多的for循环来获得正确的组合。
示例:注意:“op”词典的数量可能会有所不同!忽略这样的值,重要的是,我使用“op”字典列表来基本获取名为NoOp节点的Nuke GUI元素中的所有自定义控件。我需要迭代每个值的每个控件,进行所有可能的组合:
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
ATM这个脚本只是递归打印控件
我如何在这种情况下使用递归,更重要的是,我应该使用递归,如果是的话,我该如何处理这种情况并将其分解为它的组件?干杯,
答案
不是100%确定你想要实现的目标,但是如果你想获得所有选项的组合,你应该使用itertools.product
:
>>> list(itertools.product(op1["options"], op2["options"], op3["options"]))
[('Glass', 'Chrome', 'Red'),
('Glass', 'Chrome', 'Blue'),
('Glass', 'Chrome', 'Green'),
...
('Wood', 'Red Gold', 'Cyan'),
('Wood', 'Red Gold', 'SomeWonderfulNewColor')]
如果你想将它们与各自的control
结合起来,你可以写一个辅助函数来获得这些对,然后得到那些的product
:
>>> 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_val, options: options_vals}
到{control_val: options_vals}
。这是由from_record
函数完成的。 - 将
{control_val: options_vals}
转换为[(control_val, options_val)]
列表。这是由iter_dict
完成的。 - 在所有不同的操作中获取此类列表的产品。
- 格式和打印。 3和4由
print_combinations
处理。
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']}
以上是关于在python中使用递归来组合可变大小的列表的主要内容,如果未能解决你的问题,请参考以下文章