python - 骑自行车者到功能列表,并结合他们的结果,直到找到匹配
问题描述
我有多个使用 lambda 调用的函数列表:
a = [ lambda: func_a1(a11, a12, a13), lambda: func_a2(a21, a23) ...]
b = [ lambda: func_b1(b11, b12), lambda: func_b2(b21) ...]
函数可以返回结果或触发异常:
def func_a1(a11, a12, a13):
...do something
return result
raise CustomException
稍后在代码中,我将通过该函数循环。如果函数触发错误,我会跳过并继续下一个函数,否则我会返回。如果没有返回,则引发异常
def cycle1():
for f in a :
try:
return f()
except CustomException:
continue
raise CustomException
列表等类似def cycle2
。b
然后将来自cycle1
和的结果cycle2
结合起来并与事实来源进行比较。为简化起见,类似:
a,b = cycle1(), cycle2()
if a + b == c:
do something
该解决方案有缺陷,因为如果不匹配不会返回尝试其他组合。如果a
不b
等于c
我想获得下一个值,但我已经无法正常工作了。例如:
- 如果
a[0]
和b[0]
返回但不相等c
,则测试a[1][b0]
- 如果
a[0]
触发异常a[1]
与b[0]
. 如果不相等c
,合并a[1]
和b[1]
有函数返回的组合(没有触发错误)。我也想先a
循环b
(a循环,b状态在第一个元素上,循环将b移动到第二个元素)。
甚至可以扩展以拥有更多列表,例如a
, b
,c
作为列表。我在想也许可以使用发电机来循环。
我需要一个想法、python 或伪代码来实现它,以避免我最初解决方案的问题
解决方案
如果我理解正确,您想尝试所有功能组合,如果是这样,可以使用itertools.product来完成,例如
>>> import itertools
>>> list(itertools.product([1,2,3],"a b c".split()))
[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]
>>>
对于您的特定用途,您可以执行以下操作,但对您的循环功能进行一些更改,稍后我将展示
for a, b in itertools.product(cycle1(), cycle2()):
if a+b==c:
#do something
像这样工作所需的更改是将其转换为生成器,只需将 return 更改为 yield
def cycle1():
for f in a :
try:
yield f()
except CustomException:
continue
#raise CustomException
作为一个生成器,它将循环遍历列表中的所有函数a
,而不仅仅是在第一次成功时停止,例如return
; 尽管可能会忽略最后一个例外,如果您到达产品组合的末尾,您将知道您没有找到您要搜索的内容
这是样本生成器
>>> def gen(nums):
for n in nums:
yield 10+n
>>> list(gen([1,2,3]))
[11, 12, 13]
>>>
可以进行的另一个更改是,如果 cycle2 除了列表之外与 cycle1 相同,那么不要重复自己并让 cycle 将该列表作为参数,现在我们也有例外
def cycle(fun_list,exc=CustomException):
for f in fun_list :
try:
yield f()
except exc:
continue
以前就是现在
for a, b in itertools.product(cycle(list_a), cycle(list_b)):
if a+b==c:
#do something