国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

python高級(1): 迭代器詳解

這篇具有很好參考價值的文章主要介紹了python高級(1): 迭代器詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Python迭代器的作用是提供一種遍歷數(shù)據(jù)集合的方式。它是一個可以被迭代的對象,可以使用迭代器的方法來逐個訪問集合中的元素,而不需要事先知道集合的大小。

在深度學習的DatasetDataloader中,就是通過迭代器實現(xiàn)的,因此迭代器是一個非常重要的概念和工具

迭代器具有以下幾個重要的特點:

  • 節(jié)省內(nèi)存:迭代器一次只返回一個元素,不需要一次性將整個集合加載到內(nèi)存中,這樣可以節(jié)省內(nèi)存空間,特別是在處理大型數(shù)據(jù)集合時非常有用。
  • 惰性計算:迭代器在需要時才會計算下一個元素,而不是一次性計算所有的元素。這種惰性計算的方式可以在處理大量數(shù)據(jù)時提高效率。
  • 可逆迭代:迭代器可以反向遍歷集合,而不需要額外的復制和存儲。
  • 支持并行處理:迭代器可以同時遍歷多個集合,實現(xiàn)并行處理。

總之,迭代器提供了一種靈活、高效和節(jié)省內(nèi)存的方式來遍歷數(shù)據(jù)集合,是Python中非常重要的概念和工具。

1. 迭代器與可迭代對象(Iterable)

1.1 可迭代對象(Iterable)

表示該對象可迭代, 它的類中需要定義__iter__方法,只要是實現(xiàn)了__iter__方法的類就是可迭代對象。

from collections.abc import Iterable, Iterator

class A(object):
   def __init__(self):
       self.a = [1, 2, 3]

   def __iter__(self):
       # 此處返回啥無所謂
       return self.a

cls_a = A()
#  True
print(isinstance(cls_a, Iterable))
  • 可迭代對象,必須具備__iter__這個特殊函數(shù),并且返回一個可迭代對象。可以通過isinstance(cls_a, Iterable)可以判斷是否是可迭代對象

  • 如果一個Iterable,僅僅定義了__iter__方法,是沒有特別大的用途,因為依然無法迭代,實際上 Iterable 僅僅是提供了一種抽象規(guī)范接口

1.2 迭代器( Iterator)

  • 迭代器Iterator一定是可迭代對象Iterable,但反過來,可迭代對象不一定是迭代器,因為迭代器只是可迭代對象的一種表示形式。
  • 實現(xiàn)了__next____iter__方法的類才能稱為迭代器 就可以被 for 循環(huán)遍歷數(shù)據(jù)。

因此,通過自定義實現(xiàn)迭代器Iterator,必須具備__next____iter__ 兩個方法,如下案例所示:

class A(object):
    def __init__(self):
        self.index = -1
        self.a = [1, 2, 3]

    # 必須要返回一個實現(xiàn)了 __next__ 方法的對象,否則后面無法 for 遍歷
    # 因為本類自身實現(xiàn)了 __next__,所以通常都是返回 self 對象即可
    def __iter__(self):
        return self

    def __next__(self):
        self.index += 1
        if self.index < len(self.a):
            return self.a[self.index]
        else:
            # 拋異常,for 內(nèi)部會自動捕獲,表示迭代完成
            raise StopIteration("遍歷完了")

cls_a = A()
print(isinstance(cls_a, Iterable)) # True 
print(isinstance(cls_a, Iterator)) # True  從這里可以看出來同時具有__iter__和__next__的類,是Iterator
print(isinstance(iter(cls_a), Iterator)) # True 這里加不加iter()都一樣,因為這個類里面的iter也是直接返回自身(self)

#另外補充一點這個a和上面類里面的a是不一樣的;這里的用i(任意字母都可以)也能
for a in cls_a:
    print(a)
# 打印 1 2 3

-可以看到,通過實現(xiàn)__iter__, 和__next__這兩個特殊方法,實現(xiàn)了迭代器A。

2. 自定義一個可迭代器

2.1 實現(xiàn)迭代器

在Python中從頭開始構建迭代器很容易。我們只需要實現(xiàn)這些方法__iter__()__next__()

  • __iter__()方法需要返回迭代器對象, 最簡單直接返回self,也可以返回新的可迭代對象。如果需要,可以執(zhí)行一些初始化。
  • __next__()方法必須返回序列中的下一項。在到達終點時,以及在隨后的調(diào)用中,它必須引發(fā)StopIteration

這里,我們展示了一個示例,通過定義一個迭代器,手動實現(xiàn)python的range方法:

class Range:
    
    def __init__(self,start,stop,step):
        self.start = start  
        self.stop = stop  
        self.step = step 
             
    
    def __iter__(self):
        self.value = self.start
        return self
    
    def __next__(self):
        # 1. 每執(zhí)行一次next,需要返回一個值  
        # 2. 如果沒有下一個值了,需要通過StopIteration 反饋異常
        if self.value < self.stop:
            old_value = self.value   
            self.value = self.value +self.step  
            return old_value
        else:
            raise StopIteration()

for i in Range(0,5,1):
    print(i)

輸出結果
python高級(1): 迭代器詳解,python,python,python 高級,迭代器

我們知道python 的range方法 有三個參數(shù):start_value, stop_value和step,因此我們也定義這3個參數(shù)。

  • 首先定義類的__init__方法
  • 然后實現(xiàn)__iter__方法,并返回可迭代對象,這里返回了本身(slef)。其中在__iter__方法中,初始化了返回值self.value__iter__方法中,如果需要,可以執(zhí)行一些初始化
  • 最后通過__next__方法,定義每一次迭代輸出的值。當?shù)炅?,沒有下一個值,通過raise StopIteration(), 反饋錯誤。

在for循環(huán)中,最后反饋的raise StopIteration() erro,會被for循環(huán)處理掉,因此我們看不到報錯的提醒。

2.2 for 遍歷迭代器的過程

python高級(1): 迭代器詳解,python,python,python 高級,迭代器
通過單步調(diào)試,可以觀察到如下執(zhí)行順序:

  • (1) 首先調(diào)用__init__方法,對成員變量進行初始化
  • (2) 緊接著,進入__iter__,獲得一個迭代器對象self
  • (3) 最后進入__next__方法,執(zhí)行循環(huán)迭代過程,每迭代一次返回相應的迭代結果。最后迭代會執(zhí)行raise StopIteration()語句,此時程序結束(異常被for處理,所以沒有顯示出來)

可以看到所謂for循環(huán),本質上是就是一次次的執(zhí)行__next__方法的過程。for循環(huán)可等價如下代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-812869.html

r = Range(0,5,1)	  # __init__ 構造對象
iteration = iter(r)   # 執(zhí)行__iter__,獲得迭代器對象
#iteration =  r.__iter__()

next(iteration)      # 執(zhí)行__next__
#iteration.__next__()
next(iteration)		 # 執(zhí)行__next__
next(iteration)      # 執(zhí)行__next__
next(iteration)      # 執(zhí)行__next__
next(iteration)      # 執(zhí)行__next__
try:
    next(iteration)
except StopIteration as e:
    pass
  • 最后一次會報StopIteration 異常,因此通過try except進行處理。
  • 注:`
    • iter(r) 就是 r.__iter__()實現(xiàn)的
    • next(iteration)就是通過iteration.__next__()實現(xiàn)的

3. yolov8 Dataset實現(xiàn)案例

class LoadImages:
   # YOLOv5 image/video dataloader, i.e. `python detect.py --source image.jpg/vid.mp4`
   def __init__(self, path, img_size=640, stride=32, auto=True, transforms=None, vid_stride=1):
       """Initialize instance variables and check for valid input."""
       if isinstance(path, str) and Path(path).suffix == '.txt':  # *.txt file with img/vid/dir on each line
           path = Path(path).read_text().rsplit()
       files = []
       for p in sorted(path) if isinstance(path, (list, tuple)) else [path]:
           p = str(Path(p).resolve())
           if '*' in p:
               files.extend(sorted(glob.glob(p, recursive=True)))  # glob
           elif os.path.isdir(p):
               files.extend(sorted(glob.glob(os.path.join(p, '*.*'))))  # dir
           elif os.path.isfile(p):
               files.append(p)  # files
           else:
               raise FileNotFoundError(f'{p} does not exist')

       images = [x for x in files if x.split('.')[-1].lower() in IMG_FORMATS]
       videos = [x for x in files if x.split('.')[-1].lower() in VID_FORMATS]
       ni, nv = len(images), len(videos)

       self.img_size = img_size
       self.stride = stride
       self.files = images + videos
       self.nf = ni + nv  # number of files
       self.video_flag = [False] * ni + [True] * nv
       self.mode = 'image'
       self.auto = auto
       self.transforms = transforms  # optional
       self.vid_stride = vid_stride  # video frame-rate stride
       if any(videos):
           self._new_video(videos[0])  # new video
       else:
           self.cap = None
       assert self.nf > 0, f'No images or videos found in {p}. ' \
                           f'Supported formats are:\nimages: {IMG_FORMATS}\nvideos: {VID_FORMATS}'

   def __iter__(self):
       """Returns an iterator object for iterating over images or videos found in a directory."""
       self.count = 0
       return self

   def __next__(self):
       """Iterator's next item, performs transformation on image and returns path, transformed image, original image, capture and size."""
       if self.count == self.nf:
           raise StopIteration
       path = self.files[self.count]

       if self.video_flag[self.count]:
           # Read video
           self.mode = 'video'
           for _ in range(self.vid_stride):
               self.cap.grab()
           ret_val, im0 = self.cap.retrieve()
           while not ret_val:
               self.count += 1
               self.cap.release()
               if self.count == self.nf:  # last video
                   raise StopIteration
               path = self.files[self.count]
               self._new_video(path)
               ret_val, im0 = self.cap.read()

           self.frame += 1
           # im0 = self._cv2_rotate(im0)  # for use if cv2 autorotation is False
           s = f'video {self.count + 1}/{self.nf} ({self.frame}/{self.frames}) {path}: '

       else:
           # Read image
           self.count += 1
           im0 = cv2.imread(path)  # BGR
           assert im0 is not None, f'Image Not Found {path}'
           s = f'image {self.count}/{self.nf} {path}: '

       if self.transforms:
           im = self.transforms(im0)  # transforms
       else:
           im = letterbox(im0, self.img_size, stride=self.stride, auto=self.auto)[0]  # padded resize
           im = im.transpose((2, 0, 1))[::-1]  # HWC to CHW, BGR to RGB
           im = np.ascontiguousarray(im)  # contiguous

       return path, im, im0, self.cap, s
  dataset = LoadImages(source, imgsz=imgsz, vid_stride=vid_stride)
   dataloader = build_dataloader(dataset, batch_size, workers, shuffle, rank)
  • 可以看到Dataset,也是通過一個迭代器實現(xiàn),這樣做的好處就是:需要時才會返回處理好的數(shù)據(jù),而不需要一次性將整個集合加載到內(nèi)存中,這樣可以節(jié)省內(nèi)存空間,也提高了數(shù)據(jù)處理的效率。

到了這里,關于python高級(1): 迭代器詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【迭代器設計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    【迭代器設計模式詳解】C/Java/JS/Go/Python/TS不同語言實現(xiàn)

    迭代器模式(Iterator Pattern),是一種結構型設計模式。給數(shù)據(jù)對象構建一套按順序訪問集合對象元素的方式,而不需要知道數(shù)據(jù)對象的底層表示。 迭代器模式是與集合共存的,我們只要實現(xiàn)一個集合,就需要同時提供這個集合的迭代器,就像Java中的Collection,List、Set、Map等

    2023年04月17日
    瀏覽(15)
  • 高級編程技巧之Python裝飾器詳解

    高級編程技巧之Python裝飾器詳解

    ? 裝飾器是Python中一種強大而靈活的編程技巧,它可以用于修改或擴展函數(shù)的行為,同時又不需要修改函數(shù)的源代碼。本文將介紹Python中的裝飾器的基本概念、使用方法以及高級技巧,幫助你從入門到精通裝飾器的使用。 ? 在深入學習裝飾器之前,我們首先需要了解一些基本

    2024年02月13日
    瀏覽(46)
  • chatgpt賦能python:Python輸出方法詳解:從基礎print()到高級logging模塊

    在Python編程中,輸出是一個必不可少的步驟。然而,Python提供了多種輸出方法,如何選擇最適合的方法呢?本文將詳細介紹Python輸出的不同方法,并給出實際應用場景的示例。 最基礎的輸出方法就是使用內(nèi)置函數(shù) print() 。它可以接收多個參數(shù),并將它們以空格分隔輸出到控制

    2024年02月08日
    瀏覽(23)
  • C++迭代器(STL迭代器)iterator詳解

    C++迭代器(STL迭代器)iterator詳解

    要訪問順序容器和關聯(lián)容器中的元素,需要通過“迭代器(iterator)”進行。迭代器是一個變量,相當于容器和操縱容器的算法之間的中介。迭代器可以指向容器中的某個元素,通過迭代器就可以讀寫它指向的元素。從這一點上看,迭代器和指針類似。 迭代器按照定義方式分

    2024年02月03日
    瀏覽(22)
  • 一文詳解列表,元組,字典,集合,生成器,迭代器,可迭代對象,zip,enumerate

    ??列表,元組,字典,集合,生成器都是 python 中的可迭代對象,使用的時候經(jīng)常忘記,通過這篇博文總結一下。 ??列表( list )是 Python 中的一種數(shù)據(jù)結構,它可以存儲不同類型的數(shù)據(jù)。不同元素以逗號分隔。 使用方括號[]表示開始和結束。 不同元素以逗號分隔。 每個

    2024年02月07日
    瀏覽(118)
  • 【Java 基礎篇】Java 迭代器詳解

    在 Java 中,迭代器是一種常用的設計模式,用于遍歷集合中的元素。它提供了一種統(tǒng)一的方式來訪問集合中的元素,而不必暴露集合的內(nèi)部實現(xiàn)細節(jié)。本文將介紹 Java 迭代器的概念、使用方法和常見技巧,并提供一些示例代碼。 迭代器是一種對象,它允許按順序訪問集合中的

    2024年02月13日
    瀏覽(11)
  • 津津樂道設計模式 - 迭代器模式詳解(以購物車的場景來演示迭代器模式)

    津津樂道設計模式 - 迭代器模式詳解(以購物車的場景來演示迭代器模式)

    ?? 19年之后由于某些原因斷更了三年,23年重新?lián)P帆起航,推出更多優(yōu)質博文,希望大家多多支持~ ?? 古之立大事者,不惟有超世之才,亦必有堅忍不拔之志 ?? 個人CSND主頁——Micro麥可樂的博客 ??《Docker實操教程》專欄以最新的Centos版本為基礎進行Docker實操教程,入門

    2024年02月16日
    瀏覽(15)
  • 【STL】優(yōu)先級隊列&反向迭代器詳解

    【STL】優(yōu)先級隊列&反向迭代器詳解

    目錄 一,棧_刷題必備 二,stack實現(xiàn) 1.什么是容器適配器 2.STL標準庫中stack和queue的底層結構? 了解補充:容器——deque? 1. deque的缺陷 2. 為什么選擇deque作為stack和queue的底層默認容器 三,queue實現(xiàn) 1. 普通queue? 2,優(yōu)先級隊列(有難度) 1. 功能 2. 模擬實現(xiàn) 1). 利用迭代器_構造

    2024年02月13日
    瀏覽(20)
  • Python:可迭代對象與迭代器

    相關閱讀 Python https://blog.csdn.net/weixin_45791458/category_12403403.html?spm=1001.2014.3001.5482 ? ? ? ? 根據(jù)Python官方文檔,可迭代對象(iterable)是“一種能夠逐個返回其成員項的對象”。具體來說,這種對象要么定義了一個返回迭代器(iterator)的魔術方法__iter__(),要么定義了魔術方法__geti

    2024年04月29日
    瀏覽(16)
  • Python 基礎 - 迭代器 / 迭代器對象 / 可迭代對象 / range函數(shù)

    目錄 1. 迭代器 2.迭代器對象 3. 可迭代對象 4. range函數(shù) 1. 迭代器 當類中定義了__iter__和 __next__兩個方法 __iter__: 返回對象本身,即self __next__: 返回下一個數(shù)據(jù),如果沒有數(shù)據(jù),則拋出StopIteration異常 2.迭代器對象 通過迭代器類實例化創(chuàng)建的迭代器對象 可以通過 obj.__next__() 或

    2023年04月27日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包