2

我有一个函数数组 [f(x),g(x),...]
我想做的是根据 x 的值所在的范围调用适当的函数。

f = lambda x: x+1
g = lambda x: x-1
h = lambda x: x*x
funcs = [f,g,h]
def superFunction(x):
    if x <= 20:
      return(funcs[0](x))
    if 20 < x <= 40:
      return(funcs[1](x))
    if x > 40:
      return(funcs[2](x))

有没有更好/pythonic的方法来处理动态数量的函数

计划是沿数据部分动态生成 n 个 polyfit 函数,然后将它们组合成一个可调用函数。

4

4 回答 4

3

您将使用调度序列:

funcs = (
    (20, f),
    (40, g),
    (float('inf'), h),
)

def superFunction(x):
    for limit, f in funcs:
        if x <= limit:
            return f(x)

或者,如果函数和限制列表很大,请使用bisect搜索查找最接近的限制。

于 2013-06-26T15:11:04.000 回答
1

使用 NumPy 进行超快速选择,以防您有很多选择(否则,为什么不坚持使用“if”语句):

import numpy as np
funcs = np.array([(20,f), (40,g), (np.inf,h)])

def superFunction(x):
    idx = np.argmax(x <= funcs[:,0])
    return funcs[idx,1](x)

这与您的原始代码一样工作,但函数选择发生在 C 而不是 Python 循环中。

于 2013-06-26T15:21:19.533 回答
0

您可以使用泛型函数。例如PEAK-Rules允许这样做。您的代码如下所示:

import peak.rules as pr

def myfunc(x):
    return x * x

@pr.when(myfunc, "x <= 20")
def myfunc_f(x):
    return x + 1

@pr.when(myfunc, "20 < x <= 40")
def myfunc_g(x):
    return x - 1

>>> myfunc(10)
11
>>> myfunc(30)
29
>>> myfunc(50)
2500

泛型函数的一个优点是它们不需要在一个地方定义。myfunc_g 可以在 myfunc 的单独文件中定义。

这确实适用于一些问题,例如将自定义 JSON 编码规则添加到现有类。在你走这条路之前仔细想想,我已经看到了使用泛型函数使代码变得不必要的复杂的例子。您在上面给出的示例我将完全按照您的呈现方式进行 - 尽管我希望您的实际代码更复杂。

于 2013-06-26T15:33:04.947 回答
0

我会利用 lambdas 可以用作 dict 键的事实。从根本上说,你将这些条件与一个函数相关联,所以我认为它很合适。你只需要修改一个地方来添加新的条件,这也是一种改进。

funcs = {
    lambda x: x <= 20: lambda x: x + 1,
    lambda x: 20 < x <= 40: lambda x: x - 1,
    lambda x: x > 40: lambda x: x * x,
}

def superFunction(x):
    for condition, fn in funcs.iteritems():
        if condition(x):
            return fn(x)
于 2013-06-26T15:34:48.280 回答