2009-11-23 27 views
14

Tôi có một đối tượng với từ điển mà tôi muốn truy cập qua __getitem__ cũng như lặp lại (chỉ giá trị, khóa không quan trọng) nhưng tôi không chắc chắn cách thực hiện.Làm cách nào để sử dụng __getitem__ và __iter__ và trả về các giá trị từ một từ điển?

Ví dụ:

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 
>>> 

Làm thế nào để nói nó chỉ đơn giản là trả lại object cho từng hạng mục trong từ điển (phím không quan trọng)?

Trả lời

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

Cảm ơn - Tôi biết đó là điều dễ dàng nhưng đã có thời gian khó khăn nhất để theo dõi điều đó! Cảm kích điều đó. – thornomad

+0

Có phải 'return self.books.itervalues ​​()' tốt hơn 'return return (self.books.values ​​())'? Tôi đã tìm ra nó là một phương pháp tiện lợi cụ thể từ điển và đã rất ngạc nhiên khi thấy rằng nó trả về một đối tượng 'dictionary-valueiterator', còn đối tượng kia trả về một' listiterator'. Tuy nhiên, kết quả cuối cùng cũng vậy. –

4

Thêm phương pháp này vào Thư viện:

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

này đại biểu lặp để dict, trong đó có một phương pháp dễ dàng để lặp giá trị. Đọc về giao thức trình lặp, bao gồm các phương thức __iter__ (trên tất cả các vòng lặp) và next (__next__ trong 3.x) (chỉ trên các trình vòng lặp).

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

Bạn có thể trả về một iterator từ dữ liệu bên trong của bạn:

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

itervalues() trả về một iterator để các giá trị của từ điển.

Nếu bạn muốn kiểm soát nhiều hơn, bạn có thể làm cho __iter__ một chức năng máy phát điện

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

trong trường hợp này, máy phát điện này mang lại sự chính xác giống như các iterator trong ví dụ đầu tiên.

0

__getitem__(self,key), nơi quan trọng là một số nguyên, như self.books của bạn là một cuốn từ điển và bạn không thể làm self.books[integer]

ví dụ:

giao thức
>>>d = {'a':'sdsdsd','b':'sfsdsd'} 
>>d[0] 

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

lặp đi như thế này:

Giao thức lặp bao gồm hai phương thức. Phương thức __iter__(), phải trả về đối tượng trình lặp và phương thức next(), trả về phần tử tiếp theo từ một chuỗi. trước đây khi phương pháp __iter__ không được xác định, nó rơi trở lại __getitem__ bằng cách gọi liên tiếp __getitem__ với giá trị gia tăng cho đến khi nó cho ra chỉ mục ngoài phạm vi lỗi.

Các vấn đề liên quan