2011-08-17 13 views
5

Ho letto qualcosa su slice in python3. Poi ho scritto un programma, ho provato a implementare getitem (self, slice (s)). Codice va sotto:[python]: come implementare slice in python3?

class NewList: 
    def __init__(self, lst): 
     print('new list') 
     self._list = lst 
    def __getitem__(self, x): 
     if type(x) is slice: 
      return [ self._list[n] for n in range(x.start, x.stop, x.step) ] #error? 
     else: 
      return self._list[x] 
    ... 

nl1 = NewList([1,2,3,4,5]) 
nl1[1:3] #error occurs 

Poi ho scoperto x.step è Nessuno, che ha reso gamma sollevare un'eccezione. Quindi, come devo implementare il metodo getitem?

+0

Inoltre, la classe 'NewList' dovrebbe ereditare da' list' ... – JBernardo

+0

@JBernardo - Vuoi dire che dovrei evitare di usare gli oggetti slice esplicitamente? – Alcott

risposta

2

è necessario utilizzare il metodo slice.indices. Data la lunghezza della sequenza, restituisce una tupla di start, stop, step:

>>> s = slice(2, 5, None) 
>>> s.indices(10) 
(2, 5, 1) 

>>> [x for x in range(*s.indices(10))] 
[2, 3, 4] 

>>> s.indices(3) 
(2, 3, 1) 

>>> s.indices(0) 
(0, 0, 1) 
0

come su x.step or 1?

class NewList: 
    def __init__(self, lst): 
     print('new list') 
     self._list = lst 
    def __getitem__(self, x): 
     if type(x) is slice: 
      return [ self._list[n] for n in range(x.start, x.stop, x.step or 1) ] #error? 
     else: 
      return self._list[x] 

nl1 = NewList([1,2,3,4,5]) 
nl1[1:3] 
+0

ya, è un modo per aggirare il problema, ma secondo quello che ho letto, no. – Alcott

2

Se x è una fetta, si può fare lo stesso come l'altra condizione:

return self._list[x] 
+0

assolutamente sì, ma voglio solo sapere come farlo io stesso – Alcott

+0

@Alcott, non sono sicuro di cosa intendi con "fai da solo". –

+1

scusate, voglio dire, voglio sapere come il __getitem __ (self, slice) è implementato nella lista. – Alcott

4

Nel caso in cui non si conosce la lunghezza del vostro oggetto c'è un trucco evidente per aggirare questo parametro obbligatorio. Per esempio getitem di una sequenza infinita può assomigliare a questo:

def __getitem__(self, key) : 
    if isinstance(key, slice) : 
     m = max(key.start, key.stop) 
     return [self[ii] for ii in xrange(*key.indices(m+1))] 
    elif isinstance(key, int) : 
     #Handle int indices 

Sarà solo non se non date avviare e fermare, ma con il controllo di nessuno questa potrebbe essere gestito anche.

+0

'xrange' non esiste in python3, invece dovremmo usare' range'. anche usando questa implementazione non puoi avere slice come '[: 4]' perché 'max' non può gestire il tipo' None'. Invece dovresti controllare se start e stop non sono 'None', e se lo sono, assegnali rispettivamente a zero e len degli item. Inoltre, è bene includere anche 'key.step' in' range'. – sazary