【问题标题】:How to implement variants/variations of a function如何实现函数的变体/变体
【发布时间】:2015-06-13 23:34:43
【问题描述】:

这是我的第一个问题,因此对于我确信我会犯的任何发布错误,我深表歉意。我确实首先搜索了以前回答的问题,但我没有找到合适的解决方案,尽管我知道我可能没有使用正确的术语或关键字进行搜索。

我想在 Python 中快速评估一个通用函数。它被传递给优化器(fmin_cobyla),我希望它只接受一个参数。我希望能够选择使用可能由标志控制的此功能的不同变体(变体?口味?)。由于我希望快速评估它,因此在函数中包含一堆 if 或 case 语句是没有意义的(对吗?),所以目前我有围绕函数变体定义的 if 语句:

if flag==1:
    def f(x):
        for i in range(0,len(x)*3,3):
            A[i:i+3,i:i+3]=1/x[i/3]*np.eye(3)
        tmp=np.linalg.solve(A,b)
        y=somecmodulefunction(tmp)
        return y
elif flag==2:
    def f(x):
        for i in range(0,len(x)*3,3):
            A[i:i+3,i:i+3]=x[i/3]*np.eye(3)
        tmp=np.linalg.solve(A,b)
        y=somecmodulefunction(tmp)
        return y
...

除了一行之外,功能相同。这是正确的方法吗?有没有办法做到这一点,如果我有 10 个不同的变体,它不仅仅是一个长而笨重的代码块?

谢谢!

【问题讨论】:

  • 在函数中添加一个参数flag,然后添加一个if块来实现不同的行为。尝试遵循 DRY(不要重复自己)。
  • 如果函数需要计算 10^10 次,函数中的 if 语句不会减慢它的计算速度吗? (我在原帖中提到过)
  • 当然,添加一个语句会减慢一些非零的速度,但是如果您担心简单的if boolean_value 会影响性能,您应该使用 C 编写程序。

标签: python function variations


【解决方案1】:

为什么不将标志变量也作为输入传递给函数?

def f(x, flag):
    for i in range(0,len(x)*3,3):
        if flag == 1:
           A[i:i+3,i:i+3]=1/x[i/3]*np.eye(3)
        elif flag == 2:
           A[i:i+3,i:i+3]=x[i/3]*np.eye(3)
    tmp=np.linalg.solve(A,b)
    y=somecmodulefunction(tmp)
    return y

如果有一个默认值为flag,你可以使用,Default Argument Values

def f(x, flag=1):
    for i in range(0,len(x)*3,3):
        if flag == 1:
           A[i:i+3,i:i+3]=1/x[i/3]*np.eye(3)
        elif flag == 2:
           A[i:i+3,i:i+3]=x[i/3]*np.eye(3)
    tmp=np.linalg.solve(A,b)
    y=somecmodulefunction(tmp)
    return y

因此,当您这样做时,f(10) 函数 f() 将使用等于 1flag 执行。

如果您想使用另一个 flag 值,您可以简单地执行:f(10,2)

【讨论】:

    【解决方案2】:

    尽量少重复自己。这意味着仅指定差异,即该表达式的反转。其余的都是一样的。如果您想更改某项计算的方式,则只需在一处进行更改。

    def f(x, flag):
        for i in range(0,len(x)*3,3):
            temp = x[i/3]*np.eye(3)
            if flag-2:
                temp = 1/temp
            A[i:i+3,i:i+3] = temp
        tmp=np.linalg.solve(A,b)
        y=somecmodulefunction(tmp)
        return y
    

    flag2 时,if 分支将不会执行,因为2-2 等于0,这是一个虚假值。当flag1 时,将执行if 分支,因为1-2 等于-1,一个真实值。但是,我建议使用布尔标志(即,期望值为 TrueFalse),因此您可以只使用 if flag: 并使用 True 表示您想要反转。

    【讨论】:

    • 我认为通过flag 是一个很好的解决方案,但我发现它的测试的这个特定实现有点模糊(更明确的东西可能会更好):但如果你这样做,为什么不简单地@ 987654337@?
    猜你喜欢
    • 2022-01-03
    • 2018-12-22
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多