我想要执行以下操作:我想定义一个递归函数funct
,其中自身的最后一个引用返回一个数组temp
的数字。问题是funct
必须自己做一个积分(参见下面的代码),如果funct
可以接受冒号:
作为参数,这将非常容易。所以,到目前为止,我有这个(简化的)代码:
import numpy as np
import scipy.integrate as ints
temp = np.array([[1,2,3,4,5],[4,0,6,7,8],[7,8,9,10,11],[1,2,3,4,5],[6,7,8,9,10]])
def funct(x,y,n):
if n>1:
return (temp[x,y] + ints.cumtrapz(temp[x,:]*funct(:,y,n-1), x=None, dx=1, initial=0)[-1])
else:
return temp[x,y]
funct = np.vectorize(funct)
funct(1,1,3)
问题在于,funct
无法接受冒号:
作为参数,如果我想向量化到{{},这并不重要1}}稍后在代码中。
例如,如果我改变上面代码的这一部分
funct
代表
ints.cumtrapz(temp[x,:]*funct(:,y,n-1), x=None, dx=1, initial=0)[-1])
我没有问题。我只是想递归地做最后一部分。
答案 0 :(得分:2)
首先,Python没有像其他语言那样的“范围运算符”。 :
生成slice
s,这是与range
完全不同的类型。而且,更重要的是,:
语法是slicing(又名扩展索引或扩展订阅)语法的一部分,它不能独立存在。
因此,编写代码的简单方法是使用slice
字面值:
当然你也可以避免所有这些混乱,只使用一个明确的切片文字:
def funct(x, y, n):
if n>1:
return (temp[x,y] + ints.cumtrapz(temp[x,:]*funct(slice(None),y,n-1), x=None, dx=1, initial=0)[-1])
else:
return temp[x,y]
那么,为什么没有“切片文字”的语法比调用slice
构造函数更方便?因为没有人提出令人信服的论据,找出了潜在的语法歧义,并提交了补丁。*
*请注意,Python 自行添加省略号文字的语法 - ...
是Ellipsis
的文字,ellipsis
的单例值1}}。很多人都希望这样,除了在代码中已经非法,有人写了一个补丁之后,没有任何含糊之处,并且它被大家接受了。
虽然扩展索引的语法和函数调用的语法有些类似,但它们并不相同。这意味着你不能使用函数调用,例如,特定于域的语言来包装延迟切片。
可以做的一件事是创建一个切片包装器类型,将切片表达式本身用作特定于域的语言:
class Slicer:
def __getitem__(self, idx):
return idx
s = Slicer()
现在s[:]
是slice(None)
的构造函数,s[3:23:2, ..., 4]
是(slice(3, 23, 2), Ellipsis, 4)
的构造函数。所以你可以这样写:
funct(s[:,y,n-1])
您的funct
类将获得slice
个对象和整数的元组,以后可以通过直接调用__getitem__
来索引数组。
如果你愿意,你可以结束更多。例如:
class SliceCallable(object):
def __init__(self, f):
self.f = f
def __getitem__(self, idx):
if isinstance(idx, collections.abc.Sequence):
return self.f(*idx)
else:
return self.f(idx)
def __call__(self, *args):
return self.f(*args)
@SliceCallable
def funct(x, y, n):
if n>1:
return (temp[x,y] + ints.cumtrapz(temp[x,:]*funct[:,y,n-1], x=None, dx=1, initial=0)[-1])
else:
return temp[x,y]
现在,funct
可以被称为funct(1, 2, 3)
或funct[1, 2, 3]
- 或funct[:, 2, 3]
或funct[4:-1]
。这只意味着x
将是slice(None, None, None)
或slice(4, -1, None)
。你可以在索引表达式中使用它; temp[slice(None, None), 3]
可能看起来不像temp[:, 3]
那么好,但它意味着同样的事情。