Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数如何接受冒号(范围运算符)作为参数(在Python中)?_Python_Function_Arguments_Recurrence_Colon - Fatal编程技术网

函数如何接受冒号(范围运算符)作为参数(在Python中)?

函数如何接受冒号(范围运算符)作为参数(在Python中)?,python,function,arguments,recurrence,colon,Python,Function,Arguments,Recurrence,Colon,我要执行以下操作:我要定义一个递归函数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,

我要执行以下操作:我要定义一个递归函数
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
不能接受冒号
作为参数,如果我想在代码的后面将其矢量化为
funct
,这无关紧要

例如,如果我更改上述代码的这一部分

ints.cumtrapz(temp[x,:]*funct(:,y,n-1), x=None, dx=1, initial=0)[-1]) 
为了


我没有问题。我只想递归地完成最后一部分。

首先,Python不像其他一些语言那样具有“范围运算符”。
生成的
切片
s与
范围
s的类型完全不同。而且,更重要的是,
语法是(又称扩展索引或扩展订阅)语法的一部分,它本身并不存在

因此,编写代码的简单方法是使用
slice
literal:

当然,您也可以避免所有这些混乱,只需使用显式切片文字:

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
构造函数更方便的“slice literals”语法呢?因为没有人提出令人信服的论点,解决了潜在的语法歧义,并提交了补丁*

*请注意,Python确实自己为省略号文本添加了语法-
省略号
的文本,类型为
省略号
。很多人都希望这样,除了已经非法的代码外,没有含糊不清的地方,有人写了一个补丁,它被接受了


虽然扩展索引的语法和函数调用的语法有些相似,但它们并不相同。这意味着您不能将函数调用用作,例如,用于包装延迟切片的特定于域的语言

您可以做的一件事是创建一个切片包装器类型,以使用切片表达式本身作为特定于域的语言:

class Slicer:
    def __getitem__(self, idx):
        return idx
s = Slicer()
现在,
s[:]
slice(None)
的构造函数,
s[3:23:2,…,4]
(slice(3,23,2),省略号,4)
的构造函数。所以你可以这样写:

funct(s[:,y,n-1])
您的
funct
类将获得
slice
对象和整数的元组,它可以在以后通过直接调用数组的
\uuuu getitem\uuuu
来对数组进行索引

如果你想的话,你可以把它包起来。例如:

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]
好,但它的意思是一样的。

冒号不是Python的范围运算符或
ndarray
。dp ypu希望传递什么作为参数?注意,对于
numpy
的特殊用法,您可以使用例如
np.s\u4:6]
返回
切片
对象。看见
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]