零基礎學習 Python 之初識迭代

  • 2019 年 11 月 7 日
  • 筆記

寫在之前

大家好,這裡是零基礎學習 Python 系列,在這裡我將從最基本的Python 寫起,然後再慢慢涉及到高階以及具體應用方面。我是完全自學的 Python,所以很是明白自學對於一個人的考驗,所以在這裡我會盡我最大的努力,把 Python 儘可能簡單的表述清楚,讓更多想要學習 Python 的朋友能夠入門。同時寫這個教程也算是對自己之前所學知識的一個鞏固和提高,喜歡的朋友們可以點個關注,有問題歡迎隨時和我交流。本文所有的程式碼編寫均是Python3 版本。

在前面的文章中很多次的提到「迭代」 這個詞,但是一直沒有專門去寫它,那麼今天終於把它排上號了。當然了,迭代的這個話題要真的認真說起來的話會很多,本著循序漸進的原則,本篇文章先介紹比較初級的。

準備

在學習迭代之前,我們先來搞清楚下面這些名詞:

1.循環(loop)

循環是指在滿足條件的情況下,重複執行同一段程式碼,比如我們之前學過的 while 語句,忘記的請看這篇文章 — 零基礎學習 Python 之 while 循環語句

2.迭代(Iterate)

迭代是指按照某種順序逐個訪問對象中的每一項,比如我們之前學過的 for 語句,忘記的請看這篇文章 — 零基礎學習 Python 之 for 循環語句

3.遞歸(recursion)

遞歸是指一個函數不斷調用自身的行為,比如我們很熟悉的斐波那契數列,如果不熟悉請自行搜索,很簡單的。

4.遍歷(traversal)

遍歷是指按照一定的規則訪問樹形結構中的每個節點,而且每個節點都只訪問一次,其實 for 循環就是一種遍歷,至於什麼是樹形結構,emmmm…不是我們在這裡討論的重點。

上述的四個詞可能看起來有點高深莫測,其實我們在前面已經講過關於循環的內容,你要是在網上搜過的話,你會發現網上充斥著大量的講關於迭代,循環和遞歸區別的文章,這裡我們暫時先不比較,我們在本篇文章中先搞明白 Python 中的迭代。

逐個訪問

在 Python 中,如果你想要訪問對象中的每個元素,可以像下面這樣做,我在這以列表舉例:

>>> my_list = ['r','o','c','k','y']  >>> for i in my_list:  ...     print(i,end=' ')  ...  r o c k y >>>

除了上述方法以外,還可以像下面這樣:

>>> my_iter = iter(my_list)  >>> my_iter.__next__()  'r'  >>> my_iter.__next__()  'o'  >>> my_iter.__next__()  'c'  >>> my_iter.__next__()  'k'  >>> my_iter.__next__()  'y'  >>> my_iter.__next__()  Traceback (most recent call last):    File "<stdin>", line 1, in <module>  StopIteration

上面的 iter() 是一個內建函數,返回的就是一個迭代器對象,我在後面會專門再講迭代器。

在 Python3 中,所有的迭代器對象都有 __next()__ 方法,迭代器,當然是可迭代的,在上面的例子中,__next()__ 就是要獲得下一個對象,但是作為一個 「懶惰」 的程式設計師來說,上面的那種方法一個個的敲太麻煩了,所以就有了下面的方法:

>>> while True:  ...     print(my_iter.__next__())  ...  Traceback (most recent call last):    File "<stdin>", line 2, in <module>  StopIteration

上面出現了錯誤,我們先不管,再來它一次:

>>> my_iter = iter(my_list)  >>> while True:  ...     print(my_iter.__next__())  ...  r  o  c  k  y  Traceback (most recent call last):    File "<stdin>", line 2, in <module>  StopIteration

看了上面演示的例子可以發現,如果我們用 for 循環來寫的話,當到了末尾的時候就自動結束了,但是用了 __next__() 的話,當完成最後一個的時候它不會自動結束,還會向下繼續,但是後面已經沒有元素了,所以就發出了一個 StopIteration 的資訊,即停止迭代。

在這我們還要再關注一下迭代器對象的另一個特點,看上上個的那個例子就可以知道,對象 my_iter 被迭代結束後,即每個元素都讀取了一遍之後,指針就移到了最後一個元素後面,如果想要再訪問的話,指針並沒有自動移動到初始位置,所以會報 StopIteration,如果想要重新開始的話,就需要重新載入迭代對象。

到現在,對迭代器暫且有上述的了解,迭代器其實還要更深層次的使用,但是有一個典型的例子 — 文件,這就是為什麼我先把文件放在之前兩天的文章來講。

文件迭代器

現在有一個 「test.txt」 的文件,文件內容是:

My name is Rocky  I love Python  a,hhhhhhh

現在用迭代器來嘗試操作這個文件,我們其實在之前兩天講述有關文件的知識的時候已經講過了,就是用 readline() 一行一行的讀,當然在實際操作中,我們是絕對不會這樣做的,因為我們 「懶」 啊,一定要讓它自動進行,比較常用的方法如下:

>>> f = open('test.txt')  >>> for line in f:  ...     print(line,end=' ')  ...  My name is Rocky   I love Python   a,hhhhhhh >>>

上面的過程當然用 __next__() 也能夠讀取:

>>> f = open('test.txt')  >>> f.__next__()  'My name is Rockyn'  >>> f.__next__()  'I love Pythonn'  >>> f.__next__()  'a,hhhhhhh'  >>> f.__next__()  Traceback (most recent call last):    File "<stdin>", line 1, in <module>  StopIteration

如果用 __next__() 就可以直接讀取每行的內容,這就說明文件是天生可迭代的對象,不需要用 iter() 轉換。再者,我們用 for 來實現迭代,本質上就是自動調用 __next__() ,只不過這個工作被 for 偷偷的做了,所以 for 是活雷鋒無疑了。

寫在之後

初識迭代就到這結束了,其實迭代器遠不止上述的那麼簡單,以後我們還會不斷的遇到,我會在後續為大家帶來深入理解迭代的文章。

最後感謝你能看到這裡,希望我寫的東西能夠讓你有到收穫,但是我還是希望我在文章里插入的程式碼,你們能自己動手試一下,都很簡單。原創不易,每一個字,每一個標點都是自己手敲的,所以希望大家能多給點支援,該關注關注,該點贊點贊,該轉發轉發,有什麼問題歡迎在後台聯繫我,也可以在公眾號找到我的微信加我。