疊代器:例如 清單
疊代器模式
提供了一種方法能夠順序通路集合中的所有元素,而又不暴露集合内部的實作
疊代器的本質是實作了一種方式:
能夠判斷集合中是否還有未被通路的元素,以及提供通路這個元素的方式
代碼執行個體
# -*- coding: utf-8 -*-
# @File : 疊代器模式.py
# @Date : 2018-05-23
from abc import abstractmethod
# 定義疊代器
# 實作了兩個方法,是否還有未被通路的元素和下一個未被通路的元素
class Iterator(object):
def __init__(self):
pass
@abstractmethod
def has_next(self):
pass
@abstractmethod
def next(self):
pass
# 一個書架上擺滿了書,我們需要查找某本書時,就用到了疊代器模式
# 定義書本, 名稱和編号
class Book(object):
def __init__(self, name, number):
self.name = name
self.number = number
# 書架定義
# 書架實作了增加書目,查找index位置的數目以及總共的圖書數目這幾個方法
class BookShelf(object):
def __init__(self):
self.books = []
def append_book(self, book):
self.books.append(book)
def get_book_at(self, index):
return self.books[index]
def get_length(self):
return self.books.__len__()
# Iterator的具體實作
class BookShelfIterator(Iterator):
def __init__(self, book_shelf):
self.book_shelf = book_shelf
self.index = 0
def has_next(self):
if self.index < self.book_shelf.get_length():
return True
else:
return False
def next(self):
book = self.book_shelf.get_book_at(self.index)
self.index += 1
return book
if __name__ == "__main__":
book_shelf = BookShelf()
book_shelf.append_book(Book("國文", "001"))
book_shelf.append_book(Book("數學", "002"))
book_shelf.append_book(Book("英語", "003"))
book_shelf_iterator = BookShelfIterator(book_shelf)
# 通過hasNext方法和next方法便可以通路數目的具體資訊
while book_shelf_iterator.has_next():
book = book_shelf_iterator.next()
print(book.name, book.number)
"""
國文 001
數學 002
英語 003
"""
python實作疊代器
任何實作了
__iter__
和
__next__
方法的對象都是疊代器
__iter__
傳回疊代器自身
__next__
傳回容器中的下一個值
Python3
# 新書架python實作
class NewBookShelf(BookShelf):
def __init__(self):
self.index = 0
BookShelf.__init__(self)
# 實作容器,進行成員檢查
def __contains__(self, book):
if book in self.books:
return True
else:
return False
# 可疊代對象實作了__iter__方法
def __iter__(self):
return self
# 疊代器實作next方法
def __next__(self):
if self.index < self.get_length():
book = self.books[self.index]
self.index += 1
return book
else:
raise StopIteration # 停止标志
if __name__ == "__main__":
# 新書架
new_book_shelf = NewBookShelf()
book1 =Book("國文", "001")
new_book_shelf.append_book(book1)
new_book_shelf.append_book(Book("數學", "002"))
new_book_shelf.append_book(Book("英語", "003"))
# 成員檢查
print(book1 in new_book_shelf)
# True
# 疊代書本
for book in new_book_shelf:
print(book.name, book.number)
"""
國文 001
數學 002
英語 003
"""
Python2
# 新書架python實作
class NewBookShelf(BookShelf):
def __init__(self):
self.index = 0
BookShelf.__init__(self)
# 實作容器,進行成員檢查
def __contains__(self, book):
if book in self.books:
return True
else:
return False
# 可疊代對象實作了__iter__方法
def __iter__(self):
return self
def next(self):
if self.index < self.get_length():
book = self.books[self.index]
self.index += 1
return book
else:
raise StopIteration # 停止标志
Python3 和 Python2和 略有不同,Python3 使用
__next__
替換了
next
會報錯
TypeError: iter() returned non-iterator of type 'NewBookShelf'
是以可以寫個相容代碼
# 新書架python實作
class NewBookShelf(BookShelf):
def __init__(self):
self.index = 0
BookShelf.__init__(self)
# 實作容器,進行成員檢查
def __contains__(self, book):
if book in self.books:
return True
else:
return False
# 可疊代對象實作了__iter__方法
def __iter__(self):
return self
# 相容 Python3 和 Python2
def next(self):
return self.__next__()
# 疊代器實作next方法
def __next__(self):
if self.index < self.get_length():
book = self.books[self.index]
self.index += 1
return book
else:
raise StopIteration # 停止标志
總結
概念 | 實作 |
容器(container) | __contains__ |
可疊代對象(iterable) | __iter__ 傳回疊代器自身 |
疊代器(iterator) | __next__ 傳回容器中的下一個值 停止标志StopIteration |
生成器(generator) | yiled關鍵字 |
生成器表達式(generator expression) | [x for x in lst ] -> (x for x in lst) |
參考: