我正在尝试建立一个系统来生成一组“配置”。这些配置是存储在 python dict 中的简单键/值对。
这些配置是用一系列函数转换字典的结果,这就是我所说的工作流。
这是我最终得到的一个简单示例:
global_data = [dict()]
def workflow_step1(data):
results = []
for i in range(1,4):
data['key'] = i
results.append(copy.deepcopy(data))
return results
def workflow_step2(data):
results = []
for i in range(1,3):
data['otherkey'] = i
results.append(copy.deepcopy(data))
return results
def workflow_step3(data):
data['yetanotherkey'] = 42
return [copy.deepcopy(data)]
def list_workflow():
return [workflow_step1, workflow_step2, workflow_step3]
def merge(lhs,rhs):
return lhs+rhs
def run(data):
for step in list_workflow():
data = reduce(lambda lhs, rhs: lhs+rhs, [step(d) for d in data])
return data
print run(global_data)
这很好用,我得到:
[{'yetanotherkey': 42, 'otherkey': 1, 'key': 1},
{'yetanotherkey': 42, 'otherkey': 2, 'key': 1},
{'yetanotherkey': 42, 'otherkey': 1, 'key': 2},
{'yetanotherkey': 42, 'otherkey': 2, 'key': 2},
{'yetanotherkey': 42, 'otherkey': 1, 'key': 3},
{'yetanotherkey': 42, 'otherkey': 2, 'key': 3}]
如您所见,目标是获取字典的所有可能组合。工作流的每个步骤都会返回一组可能的组合,这应该为接下来的步骤创建一个新的可能性分支。
我面临的问题是,用户现在正在创建越来越多的工作流程步骤,从而导致组合爆炸。
我幼稚的设计中的问题是我一次生成了所有可能性的整个树。
我希望使用yield
和生成器来解决这个问题,一次生成一种可能性,因此不会同时存储所有内容。
我当然能够使用 yield 重写工作流程步骤:
def workflow_step1(data):
for i in range(1,4):
data['key'] = i
yield copy.deepcopy(data)
def workflow_step2(data):
for i in range(1,3):
data['otherkey'] = i
yield copy.deepcopy(data)
def workflow_step3(data):
data['yetanotherkey'] = 42
yield copy.deepcopy(data)
def list_workflow():
yield workflow_step1
yield workflow_step2
yield workflow_step3
但是我就是无法让我的大脑去想如何重写run
函数来依次处理每个步骤。我迷失在产量和生成器的大脑迷宫中。
任何想法都更受欢迎!