在 Python 中,我可以遍历单个值吗?

In Python can I loop over a single value?

我有一个包含 5 个变量的函数。 我想通过绘制一个跨越 2 个变量范围并保持其余 3 个不变的曲面来可视化函数的行为方式。

在我的例子中,函数是 Black Scholes,它是 S、T、K、r、s 的函数: BS(S,T,K,r,s)

我想绘制结果 BS(S,T,Kvec,r,svec) 其中 K 和 s 替换为向量输入。 要么 BS(Svec,Tvec,K,r,s) 其中 S 和 T 替换为向量输入。 要么 BS(S,Tvec,K,r,svec) 其中 T 和 K 替换为矢量输入。

总而言之,我想让用户传入 2 个向量和 3 个常量,然后让函数适应。

如何在不编写所有 5 个选择 2 个案例的情况下优雅地完成此操作?

我试过将所有输入转换为 Numpy 数组然后进行迭代,但具有单个值的 numpy 数组不可迭代。

def BS_Call_HyperCube(Svec,Kvec,Tvec,rvec,svec):
    Svec = np.asarray(Svec)
    Kvec = np.asarray(Kvec)
    Tvec = np.asarray(Tvec)
    rvec = np.asarray(rvec)
    svec = np.asarray(svec)

    for S in Svec:
        for K in Kvec:
            for T in Tvec:
                print(S,K,T)

我也试过这个:

def BS_Call_HyperCube(Svec,Kvec,Tvec,rvec,vvec):
    nS = 1 if isinstance(Svec,(int,float)) else len(Svec)
    nK = 1 if isinstance(Kvec,(int,float)) else len(Kvec)
    nT = 1 if isinstance(Tvec,(int,float)) else len(Tvec)
    nr = 1 if isinstance(rvec,(int,float)) else len(rvec)
    nv = 1 if isinstance(svec,(int,float)) else len(vvec)

    cube = np.ndarray((nS,nK,nT,nr,ns))
    
    for iS in range(nS):
        S = Svec[iS]
        for iK in range(nK):
            K = Svec[iK]
            for iT in range(nT):
                T = Svec[iT]
                for ir in range(nr):
                    r = Svec[ir]
                    for iv in range(nv):
                        v = Svec[iv]
                        
                        cube[iS,iK,iT,ir,iv] = BS_Call(S,K,T,r,v)

                        
    

在 python 中没有办法让退化循环只循环一个常量吗?

这确实不是实现这个 black scholes 东西的好方法,但是在不改变你的原始结构的情况下,你开始吧:

def BS_Call_HyperCube(Svec,Kvec,Tvec,rvec,vvec):
try:
    nS = len(Svec)
except TypeError:
    nS = 1
    Svec = [Svec]
try:
    nS = len(Kvec)
except TypeError:
    nS = 1
    Kvec = [Kvec]
try:
    nS = len(Tvec)
except TypeError:
    nS = 1
    Tvec = [Tvec]
try:
    nS = len(rvec)
except TypeError:
    nS = 1
    rvec = [rvec]
try:
    nS = len(vvec)
except TypeError:
    nS = 1
    vvec = [vvec]
cube = np.ndarray((nS,nK,nT,nr,ns))

for iS in range(nS):
    S = Svec[iS]
    for iK in range(nK):
        K = Svec[iK]
        for iT in range(nT):
            T = Svec[iT]
            for ir in range(nr):
                r = Svec[ir]
                for iv in range(nv):
                    v = Svec[iv]
                    
                    cube[iS,iK,iT,ir,iv] = BS_Call(S,K,T,r,v)

显然要遍历 python 中的常量只需要将该常量放入列表中以使其可迭代。谢谢大家的回答。 关于使常量可迭代的下一步...... 使用 isinstance 检查数据类型似乎比 try catch 更优雅。 如果这不正确,请告诉我。 下面是我的解决方案。再次感谢大家。

S = 100; K = 100; T = 1; r = .05; s = .32

K = np.linspace(20,70,11)
T = np.linspace(.10,.60,11)

if isinstance(S,(int,float)):
    nS = 1
    Svec = [S]
else:
    nS = len(S)
    Svec = S

if isinstance(T,(int,float)):
    nT = 1
    Tvec = [T]
else:
    nT = len(T)
    Tvec = T

if isinstance(K,(int,float)):
    nK = 1
    Kvec = [K]
else:
    nK = len(K)
    Kvec = K

if isinstance(r,(int,float)):
    nr = 1
    rvec = [r]
else:
    nr = len(r)
    rvec = r

if isinstance(s,(int,float)):
    ns = 1
    svec = [s]
else:
    ns = len(s)
    svec = s


cube = np.ndarray((nS,nK,nT,nr,ns))

for iS in range(nS):
    xS = Svec[iS]
    for iK in range(nK):
        xK = Kvec[iK]
        for iT in range(nT):
            xT = Tvec[iT]
            for ir in range(nr):
                xr = rvec[ir]
                for iv in range(ns):
                    xs = svec[iv]
                    
                    cube[iS,iK,iT,ir,iv] = BS_Call(xS,xK,xT,xr,xs)
                    

square = np.squeeze(cube)
square.shape