2009-11-23 15 views
14

Ho un oggetto con un dizionario al quale voglio accedere tramite __getitem__ oltre a scorrere (solo valori, i tasti non hanno importanza) ma non sono sicuro di come farlo.Come utilizzare __getitem__ e __iter__ e restituire valori da un dizionario?

Ad esempio:

Python 2.5.2 (r252:60911, Jul 22 2009, 15:33:10) 
>>> class Library(object): 
... def __init__(self): 
...  self.books = { 'title' : object, 'title2' : object, 'title3' : object, } 
... def __getitem__(self, i): 
...  return self.books[i] 
... 
>>> library = Library() 
>>> library['title'] 
<type 'object'> 
>>> for book in library: 
... print book 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 5, in __getitem__ 
KeyError: 0 
>>> 

Come faccio a dire che per tornare semplicemente la object per ogni voce nel dizionario (la chiave non importa)?

risposta

22
def __iter__(self): return self.books.itervalues() 
+0

Grazie - Sapevo che era qualcosa di semplice ma stavo avendo il momento più difficile rintracciarlo! Apprezzalo. – thornomad

+0

È 'return self.books.itervalues ​​()' meglio di 'return iter (self.books.values ​​())'? Ho pensato che fosse un metodo di convenienza specifico del dizionario e sono rimasto sorpreso nel constatare che restituisce un oggetto 'dizionario-valueiterator', mentre l'altro restituisce un' listiterator'. Lo stesso risultato finale, però. –

4

Aggiungi questo metodo per Biblioteca:

def __iter__(self): 
    return self.books.itervalues() 

Questo delegati iterazione al dict, che ha un metodo facile per scorrere i valori. Leggi il protocollo iteratore, che consiste di __iter__ (su tutti gli iterabili) e next (__next__ in 3.x) (solo su iteratori).

2
>>> class Library(object): 
...  def __init__(self):              
...    self.books = { 'title' : object, 'title2' : object, 'title3' : object, } 
...  def __getitem__(self, i): 
...    return self.books[i] 
...  def __iter__(self): 
...    return self.books.itervalues() 
... 
>>> library = Library() 
>>> library['title'] 
<type 'object'> 
>>> for book in library: 
...  print book 
... 
<type 'object'> 
<type 'object'> 
<type 'object'> 
2

È possibile restituire un iteratore dai dati interna:

class Library (object): 
    ... 
    def __iter__(self): 
    return self.books.itervalues() 

itervalues() restituisce un iteratore ai valori del dizionario.

Se si desidera un maggiore controllo, è possibile effettuare __iter__ una funzione di generatore di

class Library (object): 
    ... 
    def __iter__(self): 
    for title in self.books: 
     yield self.books[title] 

in questo caso, questo generatore produce esattamente lo stesso come l'iteratore nel primo esempio.

0

__getitem__(self,key), dove la chiave è un intero, come i vostri self.books è un dizionario e non si può fare self.books[integer]

esempio:

protocollo
>>>d = {'a':'sdsdsd','b':'sfsdsd'} 
>>d[0] 

d[0] 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
KeyError: 0 

l'iterazione va in questo modo:

Il protocollo iteratore consiste di due metodi. Il metodo __iter__(), che deve restituire l'oggetto iteratore e il metodo next(), che restituisce l'elemento successivo da una sequenza. in precedenza, quando il metodo __iter__ non è stato definito, è tornato a __getitem__ chiamando in successione __getitem__ con valori crescenti fino a dare l'errore di indice fuori intervallo.

Problemi correlati