iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Software Development

燃燒大三的成果發表系列 第 11

燃燒大三的成果發表第十一天 - Iterator

  • 分享至 

  • xImage
  •  

今天我們要介紹生成器,為甚麼要使用生成器,就是能夠減少負擔、增加速度,簡單來說就是使用生成器的話不需要將整個序列資料儲存在記憶體中。

在那之前,我們要先介紹iterator(迭代器)、iterable(可迭代的),在python之中序列結構的資料類型,每一種都是可迭代的。

you define with an __iter__() method or with a __getitem__() method that implements Sequence semantics. - 「3.10.6 Python Documentation

根據官方文件對可迭代的定義,我們可以試著做一些測試的程式碼中去查看:


print(isinstance("鐵人賽", Iterable))
# True
print(dir("鐵人賽"))

print(isinstance(["鐵", "人", "賽"], Iterable))
# True
print(dir(["鐵", "人", "賽"]))

print(isinstance(("鐵", "人", "賽"), Iterable))
# True
print(dir(("鐵", "人", "賽")))

print(isinstance({"鐵", "人", "賽"}, Iterable))
# True
print(dir({"鐵", "人", "賽"}))

print(isinstance({1: "鐵", 2: "人", 3: "賽"}, Iterable))
# True
print(dir({1: "鐵", 2: "人", 3: "賽"}))

我會isinstance查看資料類型是不是可迭代,以及可以用dir分別找出他們能夠使用的方法,如果有印出來看的夥伴會發現,這些能迭代的資料裡面,可以發現含有「__iter__ 」和「__getitem__ 」這兩種方法,甚至我們可以自己定義這兩個方法試看看

class Iter():
    def __init__(self, *args):
        self.text = args

    def __iter__(self):
        return self
    
    def __getitem__(self, index):
        print("__getitem__", index)


test = Iter(5, 2, 3, 1, 4)
print(isinstance(test, Iterable))
# True

然後我們將這些可迭代的資料,轉換成迭代器(iterator)之後再查看一次情況。

print(iter("鐵人賽"))
# <str_iterator object at 0x7fa43ca59588>
print(isinstance(iter("鐵人賽"), Iterator))
# True
print(dir(iter("鐵人賽")))

轉換成迭代器之後的情況,我們其實後面可以發現迭代器裡面的方法「__iter__ 」和「__next__

An object representing a stream of data. Repeated calls to the iterator’s __next__() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its __next__() method just raise StopIteration again. Iterators are required to have an __iter__()method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. - 「3.10.6 Python Documentation

從官方文件的定義,我們可以知道迭代器裡面都會有「__iter__ 」它會回傳疊代器物件本身,然後透過「__next__ 」一直將迭代的資料取出,所以我們可以知道iterator裡面一定會有這兩個方法。

再來是iterator還有一個很重要的地方,就是迭代器的資料只能取一次,我們從官方文件也能找到定義。

Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container. - 「3.10.6 Python Documentation

不過定義歸定義,親手做到的;親眼看見的,那才是真的,所以我們馬上做個簡單的範例:

test = iter([5, 2, 3, 1, 4])
for i in (1, 2):
    for j in test:
        print(j)

將一筆可迭代的資料變成迭代器,然後將資料取出,並且嘗試重複兩次,會發現結果如同文件上寫的,只能取出一次資料,印完就沒了。

小小做個總結

iterable iterator
定義 具有__iter__() & __getitem__()方法 具有__iter__ & __next__方法。值只能取一次

迭代器在這邊告一段落,明天我們就要進入generator !!


上一篇
燃燒大三的成果發表第十天 - Decorator(裝飾器)
下一篇
燃燒大三的成果發表第十二天 - Generator
系列文
燃燒大三的成果發表30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言