Python: реализация нарезки в getitem
Я пытаюсь реализовать функциональность среза для класса, который я делаю, что создает векторное представление.
у меня есть этот код до сих пор, который я считаю, будет правильно реализовать срез, но всякий раз, когда я делаю вызов, как v[4] где v-вектор python возвращает ошибку о том, что недостаточно параметров. Поэтому я пытаюсь выяснить, как определить getitem специальный метод в моем классе для обработки как простых индексов, так и нарезки.
def __getitem__(self, start, stop, step):
index = start
if stop == None:
end = start + 1
else:
end = stop
if step == None:
stride = 1
else:
stride = step
return self.__data[index:end:stride]
5 ответов:
The
__getitem__()метод получитsliceобъект, когда объект нарезается. Просто посмотрите наstart,stopиstepчлены
у меня есть "синтетический" список (тот, где данные больше, чем вы хотели бы создать в памяти) и мой
__getitem__выглядит так:def __getitem__( self, key ) : if isinstance( key, slice ) : #Get the start, stop, and step from the slice return [self[ii] for ii in xrange(*key.indices(len(self)))] elif isinstance( key, int ) : if key < 0 : #Handle negative indices key += len( self ) if key < 0 or key >= len( self ) : raise IndexError, "The index (%d) is out of range."%key return self.getData(key) #Get the data from elsewhere else: raise TypeError, "Invalid argument type."срез не возвращает тот же тип, который является Нет-нет, но он работает для меня.
как определить класс getitem для обработки как простых индексов, так и нарезки?
объекты среза автоматически создаются при использовании двоеточия в нотации подстрочного индекса-и это это то, что передается
__getitem__. Используйтеisinstanceчтобы проверить, есть ли у вас объект slice:from __future__ import print_function class Sliceable(object): def __getitem__(self, given): if isinstance(given, slice): # do your handling for a slice object: print(given.start, given.stop, given.step) else: # Do your handling for a plain index print(given)пример использования:
>>> sliceme = Sliceable() >>> sliceme[1] 1 >>> sliceme[2] 2 >>> sliceme[:] None None None >>> sliceme[1:] 1 None None >>> sliceme[1:2] 1 2 None >>> sliceme[1:2:3] 1 2 3 >>> sliceme[:2:3] None 2 3 >>> sliceme[::3] None None 3 >>> sliceme[::] None None None >>> sliceme[:] None None None
правильный способ сделать это, чтобы иметь
__getitem__возьмите один параметр, который может быть либо числом, либо объектом среза.посмотреть:
http://docs.python.org/library/functions.html#slice
http://docs.python.org/reference/datamodel.html#object.__getitem__
расширить ответ Аарона, для таких вещей, как
numpy, вы можете сделать многомерную нарезку, проверив, еслиgiven- этоtuple:class Sliceable(object): def __getitem__(self, given): if isinstance(given, slice): # do your handling for a slice object: print("slice", given.start, given.stop, given.step) elif isinstance(given, tuple): print("multidim", given) else: # Do your handling for a plain index print("plain", given) sliceme = Sliceable() sliceme[1] sliceme[::] sliceme[1:, ::2]"'
выход:
('plain', 1) ('slice', None, None, None) ('multidim', (slice(1, None, None), slice(None, None, 2)))
Comments