天天看點

Python的iterable、iterator、sequence

1、背景

   在工作中,我們往往需要定義自己的資料結構,能夠使資料進行有效的讀取、序列結構就是重要的資料結構之一,利用python中的list、tuple、str、dict等都是一些内置的序列結構,我們可以用len()函數傳回序列長度或者for循環進行周遊元素,但實際上python的解釋器會在實作這些功能自動調用資料類中的特殊方法,例如len()調用的就是__len__(),for循環調用的是__iter__(),實際上python中的特殊方法是非常強大,能夠幫助我們有效的利用資料。

2、iterable、iterator、sequence

這裡來說一說iterable和iterator、以及sequence的差別。

iterable實際上是一個類對象,任何包含__iter__()或者__getitem__()的方法的對象,都可以被認為是一個iterable。

sequence首先iterable的一種,顧名思義,sequence就是有有序的iterable,可以通過整數索引來通路其中的元素。是以在sequence中需要定義__len__()和__getitem__()方法。

iterator對象的實作必須滿足疊代協定,python中這種疊代協定通過__next__()和__iter__()來實作。

(在hash類型資料中,__iter__()不能被__getitem__()代替。)

iterator用next()函數或者__next__()來通路元素,且每次通路iterator都會更新,能夠更有效率的利用記憶體(通路完iterator就被清空了)。

這裡放一個前面深度學習定義的資料序列:

import os
from torch import nn
from PIL import Image
import numpy as np

class Mydataset(nn.module):
    def __init__(self, images_dir:str,masks_dir:str, class_num:int, transform):
        super(Mydataset,self).__init__():
        self.class_num=class_num
        self.names=os.listdir(images_dir)
        self.images_fps=[os.path.join(images_dir,name) for name in self.names]
        self.masks_fps = [os.path.join(masks_dir, name.split(".")[0]+".npy") for name in self.names]
        self.transform=transform

    def __len__(self):
        return len(self.ids)

    def __getitem__(self, i):
        per_image=Image.open(self.images_fps[i])
        per_mask=np.load(self.masks_fps[i])
        per_mask[per_mask>self.class_num-1]=0
        per_image=self.transform(per_image)

        return per_image,per_mask
           

可以明顯的看出這是一個sequence。