我有一个给定的功能
def unnorm(x, alpha, beta):
return (1 + alpha * x + beta * x ** 2)
Run Code Online (Sandbox Code Playgroud)
然后我将其集成以查找范围内的归一化常量,并将其转换为采用相同参数的lambda函数unnorm.现在,为了创建一个合适的对象,我将这些函数组合在一起:
def normalized(x, alpha, beta):
return unnorm(x, alpha, beta) * norm(x, alpha, beta)
Run Code Online (Sandbox Code Playgroud)
这很好,但仍然有重复,并从全局命名空间中提取名称.
如何以更干净的方式组合这两个功能,而无需重新编写参数?例如
def normalized(func, normalizer):
return func * normalizer
Run Code Online (Sandbox Code Playgroud)
完整代码:
import sympy
import numpy as np
import inspect
def normalize_function(f, xmin, xmax):
"""
Normalizes function to PDF in the given range
"""
# Get function arguments
fx_args = inspect.getfullargspec(f).args
# Convert to symbolic notation
symbolic_args = sympy.symbols(fx_args)
# Find definite integral
fx_definite_integral = sympy.integrate(f(*symbolic_args), (symbolic_args[0], xmin, xmax))
# Convert to a normalization multiplication term, as a real function
N = sympy.lambdify(expr = 1 / fx_definite_integral, args = symbolic_args)
return N
def unnorm(x, alpha, beta):
return (1 + alpha * x + beta * x ** 2)
norm = normalize_function(unnorm, -1, 1)
# How do I condense this to a generic expression?
def normalized(x, alpha, beta):
return unnorm(x, alpha, beta) * norm(x, alpha, beta)
x = np.random.random(100)
print(normalized(x, alpha = 0.5, beta = 0.5))
Run Code Online (Sandbox Code Playgroud)
我现在所做的事情没有任何问题.但出于审美目的,这里有一些具有一些最小功能的替代方案.
def doubler(x, y, z):
return 2*(x + y + z)
def halver(x, y, z):
return 0.5*(x + y + z)
def doubler_halver_sumprod(*args):
return doubler(*args) * halver(*args)
dhs = lambda *args: doubler(*args) * halver(*args)
doubler_halver_sumprod(1, 2, 3) # 36
dhs(1, 2, 3) # 36
Run Code Online (Sandbox Code Playgroud)
如果你想要一个真正可扩展的,功能性的方法,一次提取参数,这可能有效:
from operator import mul, methodcaller
from functools import reduce
def prod(iterable):
return reduce(mul, iterable, 1)
def doubler(x, y, z):
return 2*(x + y + z)
def halver(x, y, z):
return 0.5*(x + y + z)
def dhs2(*args):
return prod(map(methodcaller('__call__', *args), (doubler, halver)))
def dhs3(*args):
return prod(f(*args) for f in (doubler, halver))
dhs2(1, 2, 3) # 36
dhs3(1, 2, 3) # 36
Run Code Online (Sandbox Code Playgroud)