Во-первых, у 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 сделал добавить синтаксис для многоточия литералов на их own- ...
является буквальной для Ellipsis
, одноэлементное значение типа ellipsis
. Многие хотели этого, не было никаких двусмысленностей, кроме кода, который был уже незаконным, кто-то написал патч, и это было принято с небольшой суетой.
Хотя синтаксис для расширенной индексации и синтаксис для вызовов функции несколько похожи, они не идентичны. Это означает, что вы не можете использовать вызовы функций как, например, язык, специфичный для домена, для обертывания отложенной нарезки.
Одна вещь, вы может сделать, это создать тип ломтика-обертку, чтобы с помощью самих нарезая выражения в качестве такого предметно-ориентированного языка:
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]
-or как 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 хочет передать в качестве аргумента? – wwii