Python: Implementing slicing in getitem
Próbuję zaimplementować funkcjonalność slice dla tworzonej przeze mnie klasy, która tworzy reprezentację wektorową.
Mam ten kod do tej pory, który wierzę, że poprawnie zaimplementuje kawałek, ale za każdym razem, gdy wykonuję wywołanie jak v[4]
Gdzie V jest wektorem python zwraca błąd o niewystarczającej ilości parametrów. Więc staram się dowiedzieć, jak zdefiniować getitem
specjalną metodę w mojej klasie, aby obsługiwać zarówno zwykłe indeksy, jak i krojenie.
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 answers
Metoda __getitem__()
otrzyma obiekt slice
, gdy obiekt zostanie przecięty. Wystarczy spojrzeć na start
, stop
, i step
członków obiektu slice
w celu uzyskania komponentów dla plasterka.
>>> class C(object):
... def __getitem__(self, val):
... print val
...
>>> c = C()
>>> c[3]
3
>>> c[3:4]
slice(3, 4, None)
>>> c[3:4:-2]
slice(3, 4, -2)
>>> c[():1j:'a']
slice((), 1j, 'a')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-29 22:56:39
Mam "syntetyczną" listę (taką, w której dane są większe niż chciałbyś utworzyć w pamięci) i moja __getitem__
wygląda tak:
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."
Plasterek nie zwraca tego samego typu, CO Nie-Nie, ale działa na mnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-03 03:15:33
Jak zdefiniować klasę getitem do obsługi zarówno zwykłych indeksów, jak i slicingu?
Obiekty Slice są tworzone automatycznie, gdy używasz dwukropka w notacji dolnej - i to jest tym, co jest przekazywane do __getitem__
. Użyj isinstance
, aby sprawdzić, czy masz obiekt 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)
Przykładowe użycie:
>>> 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-22 21:47:42
Poprawnym sposobem jest pobranie __getitem__
jednego parametru, który może być liczbą lub obiektem slice.
Zobacz:
http://docs.python.org/library/functions.html#slice
http://docs.python.org/reference/datamodel.html#object.__getitem__
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 01:07:04
Aby rozszerzyć odpowiedź Aarona, dla rzeczy takich jak numpy
, możesz wykonać wielowymiarowe krojenie, sprawdzając, czy given
jest 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]
```
Wyjście:
('plain', 1)
('slice', None, None, None)
('multidim', (slice(1, None, None), slice(None, None, 2)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-25 01:35:09